home *** CD-ROM | disk | FTP | other *** search
/ CD BIT 75 / CD BIT 75.iso / Software / SinfoSeguros / MSDE / Setup / SqlRun.cab / replsys.sql.24170C3F_A9E4_47C1_8DFE_FD79C2714697 < prev    next >
Encoding:
Text File  |  2002-12-11  |  1.0 MB  |  32,710 lines

Text Truncated. Only the first 1MB is shown below. Download the file for the complete contents.
  1.  
  2. /*
  3. ** replsys.sql            1997/02/12 22:03
  4. **
  5. **
  6. ** Copyright Microsoft, Inc. 1998-2000
  7. ** All Rights Reserved.
  8. */
  9.  
  10.  
  11. dump tran master with no_log
  12. go
  13.  
  14. exec dbo.sp_configure 'update',1
  15. go
  16. reconfigure with override
  17. go
  18.  
  19. set ANSI_NULLS off
  20. go
  21.  
  22. use master
  23. go
  24.  
  25. exec dbo.sp_MS_upd_sysobj_category 1 --Capture time for use at the end
  26. go
  27.  
  28. if exists( select * from sysobjects 
  29.     where type = 'P ' and name = N'sp_getarticlepkcolbitmap')
  30. begin
  31.     drop procedure sp_getarticlepkcolbitmap
  32. end
  33. go
  34.  
  35. if exists( select * from sysobjects 
  36.     where type = 'P ' and name = N'sp_isarticlecolbitset' )
  37. begin
  38.     drop procedure sp_isarticlecolbitset
  39. end
  40. go
  41.  
  42. if exists (select * from sysobjects
  43.     where type = 'P '
  44.             and name = 'sp_MSsubst_filter_name')
  45.     drop procedure sp_MSsubst_filter_name
  46. go
  47.  
  48. if exists (select * from sysobjects
  49.     where type = 'P '
  50.             and name = 'sp_MSretrieve_publication_attributes')
  51.     drop procedure sp_MSretrieve_publication_attributes
  52. go
  53.  
  54. if exists (select * from sysobjects
  55.     where type = 'P '
  56.             and name = 'sp_MScleanup_publication_ADinfo')
  57.     drop procedure sp_MScleanup_publication_ADinfo
  58. go
  59.  
  60. if exists (select * from sysobjects
  61.     where type = 'P '
  62.             and name = 'sp_MSCleanupForPullReinit')
  63.     drop procedure sp_MSCleanupForPullReinit
  64.  
  65. if exists (select * from sysobjects
  66.     where type = 'P '
  67.             and name = 'sp_MSsubst_filter_names')
  68.     drop procedure sp_MSsubst_filter_names
  69. go
  70.  
  71. if exists (select * from sysobjects
  72.     where type = 'P '
  73.             and name = 'sp_MSreplcheck_name')
  74.     drop procedure sp_MSreplcheck_name
  75. go
  76.  
  77. if exists (select * from sysobjects
  78.     where type = 'P '
  79.             and name = 'sp_MSreplcheck_publish')
  80.     drop procedure sp_MSreplcheck_publish
  81. go
  82.  
  83. if exists (select * from sysobjects
  84.     where type = 'P '
  85.             and name = 'sp_MSsetaccesslist')
  86.     drop procedure sp_MSsetaccesslist
  87. go
  88.  
  89. if exists (select * from sysobjects
  90.     where type = 'P '
  91.             and name = 'sp_MScheck_subscription')
  92.     drop procedure sp_MScheck_subscription
  93. go
  94.  
  95. if exists (select * from sysobjects
  96.     where type = 'P '
  97.             and name = 'sp_MSenumcolumns')
  98.     drop procedure sp_MSenumcolumns
  99. go
  100.  
  101. if exists (select * from sysobjects
  102.     where type = 'P '
  103.             and name = 'sp_MSlocktable')
  104.     drop procedure sp_MSlocktable
  105. go
  106.  
  107. if exists (select * from sysobjects
  108.     where type = 'P '
  109.             and name = 'sp_MSreplcheck_connection')
  110.     drop procedure sp_MSreplcheck_connection
  111. go
  112.  
  113. if exists (select * from sysobjects
  114.     where type = 'P '
  115.             and name = 'sp_MSrepl_PAL_rolecheck')
  116.     drop procedure sp_MSrepl_PAL_rolecheck
  117. go
  118.  
  119. if exists (select * from sysobjects
  120.     where type = 'P '
  121.             and name = 'sp_MSreplcheck_pull')
  122.     drop procedure sp_MSreplcheck_pull
  123. go
  124.  
  125. if exists (select * from sysobjects
  126.     where type = 'P '
  127.             and name = 'sp_MSchange_retention')
  128.     drop procedure sp_MSchange_retention
  129.  
  130. if exists (select * from sysobjects
  131.     where type = 'P '
  132.             and name = 'sp_MShelp_identity_property')
  133.     drop procedure sp_MShelp_identity_property
  134. go
  135.  
  136. if exists (select * from sysobjects
  137.     where type = 'P '
  138.             and name = 'sp_MSreplcheck_qv')
  139.     drop procedure sp_MSreplcheck_qv
  140. go
  141.  
  142. if exists (select * from sysobjects
  143.     where type = 'P' and
  144.             name = 'sp_MSreleaseSlotLock')
  145.     drop procedure sp_MSreleaseSlotLock
  146.  
  147. if exists (select * from sysobjects
  148.     where type = 'P' and
  149.             name = 'sp_MSacquireSlotLock')
  150.     drop procedure sp_MSacquireSlotLock
  151. go
  152.  
  153. if exists (select * from sysobjects
  154.     where type = 'P' and
  155.             name = 'sp_MSacquireHeadofQueueLock')
  156.     drop procedure sp_MSacquireHeadofQueueLock
  157. go
  158.  
  159. if exists (select * from sysobjects
  160.     where type = 'P '
  161.             and name = 'sp_MSpublicationcleanup')
  162.     drop procedure sp_MSpublicationcleanup
  163.  
  164. if exists (select * from sysobjects
  165.     where type = 'P '
  166.             and name = 'sp_MSUpgradeConflictTable')
  167.     drop procedure sp_MSUpgradeConflictTable
  168.  
  169. if exists (select * from sysobjects
  170.     where type = 'P '
  171.             and name = 'sp_MSaddanonymousreplica')
  172.     drop procedure sp_MSaddanonymousreplica
  173.         
  174. if exists (select * from sysobjects
  175.                 where type = 'P' and
  176.                 name = 'sp_reinitmergepullsubscription')
  177.         drop procedure sp_reinitmergepullsubscription
  178.  
  179. if exists (select * from sysobjects
  180.     where type = 'P '
  181.             and name = 'sp_expired_subscription_cleanup')
  182.     drop procedure sp_expired_subscription_cleanup
  183.     
  184.     if exists (select * from sysobjects
  185.     where type = 'P '
  186.             and name = 'sp_MSarticlecleanup')
  187.     drop procedure sp_MSarticlecleanup
  188.  
  189.  
  190.     if exists (select * from sysobjects
  191.     where type = 'P '
  192.             and name = 'sp_MSdroparticleprocs')
  193.     drop procedure sp_MSdroparticleprocs
  194.  
  195.     if exists (select * from sysobjects
  196.     where type = 'P '
  197.             and name = 'sp_MSdroparticletriggers')
  198.     drop procedure sp_MSdroparticletriggers
  199.  
  200.     if exists (select * from sysobjects
  201.     where type = 'P '
  202.             and name = 'sp_MScheckvalidsystables')
  203.     drop procedure sp_MScheckvalidsystables
  204.  
  205. if exists (select * from sysobjects
  206.     where type = 'P '
  207.             and name = 'sp_MSreplcheck_subscribe')
  208.     drop procedure sp_MSreplcheck_subscribe
  209. go
  210.  
  211. if exists (select * from sysobjects
  212.     where type = 'P '
  213.             and name = 'sp_replicationoption')
  214.     drop procedure sp_replicationoption
  215. go
  216.  
  217. if exists (select * from sysobjects
  218.     where type = 'P '
  219.             and name = 'sp_helpreplicationoption')
  220.     drop procedure sp_helpreplicationoption
  221. go
  222.  
  223. if exists (select * from sysobjects
  224.         where type in ('P ') 
  225.             and name = 'sp_MSmergesubscribedb')
  226.     drop procedure sp_MSmergesubscribedb
  227.  
  228. if exists (select * from sysobjects
  229.         where type in ('P ') 
  230.             and name = 'sp_MSremovedbreplication')
  231.     drop procedure sp_MSremovedbreplication
  232.  
  233. if exists (select * from sysobjects
  234.     where type = 'P '
  235.             and name = 'sp_addpullsubscription')
  236.     drop procedure sp_addpullsubscription
  237.  
  238. if exists (select * from sysobjects
  239.     where type = 'P '
  240.             and name = 'sp_reinitpullsubscription')
  241.     drop procedure sp_reinitpullsubscription
  242.     
  243. if exists (select * from sysobjects
  244.     where type = 'P '
  245.             and name = 'sp_addmergepullsubscription')
  246.     drop procedure sp_addmergepullsubscription
  247.  
  248. if exists (select * from sysobjects
  249.     where type = 'P '
  250.             and name = 'sp_dropmergepullsubscription')
  251.     drop procedure sp_dropmergepullsubscription
  252.  
  253. if exists (select * from sysobjects
  254.     where type = 'P '
  255.             and name = 'sp_adjustpublisheridentityrange')
  256.     drop procedure sp_adjustpublisheridentityrange
  257.  
  258. if exists (select * from sysobjects
  259.     where type = 'P '
  260.             and name = 'sp_changemergepullsubscription')
  261.     drop procedure sp_changemergepullsubscription
  262.  
  263. if exists (select * from sysobjects
  264.     where type = 'P '
  265.             and name = 'sp_helpmergepullsubscription')
  266.     drop procedure sp_helpmergepullsubscription
  267.  
  268. if exists (select * from sysobjects
  269.     where type = 'P '
  270.             and name = 'sp_MSchange_priority')
  271.     drop procedure sp_MSchange_priority
  272.  
  273. if exists (select * from sysobjects
  274.         where type = 'P '
  275.                 and name = 'sp_MSdrop_mergesystables')
  276.         drop procedure sp_MSdrop_mergesystables
  277.  
  278. if exists (select * from sysobjects
  279.         where type = 'P '
  280.                 and name = 'sp_MScreate_mergesystables')
  281.         drop procedure sp_MScreate_mergesystables
  282. go
  283.     
  284. if exists (select * from sysobjects
  285.     where type = 'P '
  286.             and name = 'sp_MSupdatesharedagentproperties')
  287.     drop procedure sp_MSupdatesharedagentproperties
  288.  
  289. if exists (select * from sysobjects
  290.     where type = 'P '
  291.             and name = 'sp_MSfixupsharedagentproperties')
  292.     drop procedure sp_MSfixupsharedagentproperties
  293.  
  294. if exists (select * from sysobjects
  295.     where type = 'P '
  296.             and name = 'sp_MSfixupdistributorinfo')
  297.     drop procedure sp_MSfixupdistributorinfo
  298.  
  299. if exists (select * from sysobjects
  300.     where type = 'P '
  301.             and name = 'sp_MSfixupdistributorsecurity')
  302.     drop procedure sp_MSfixupdistributorsecurity
  303.  
  304. if exists (select * from sysobjects
  305.     where type = 'P '
  306.             and name = 'sp_MSfixupftpinfo')
  307.     drop procedure sp_MSfixupftpinfo
  308.  
  309. if exists (select * from sysobjects
  310.     where type = 'P '
  311.             and name = 'sp_MSfixupaltsnapshotfolder')
  312.     drop procedure sp_MSfixupaltsnapshotfolder
  313.  
  314. if exists (select * from sysobjects
  315.     where type = 'P '
  316.             and name = 'sp_MSfixupworkingdirectory')
  317.     drop procedure sp_MSfixupworkingdirectory
  318.  
  319. if exists (select * from sysobjects
  320.     where type = 'P '
  321.             and name = 'sp_MSfixupuseftp')
  322.     drop procedure sp_MSfixupuseftp
  323.  
  324. if exists (select * from sysobjects
  325.     where type = 'P '
  326.             and name = 'sp_MSfixupagentoffloadinfo')
  327.     drop procedure sp_MSfixupagentoffloadinfo
  328.  
  329. go
  330.  
  331. if exists (select * from sysobjects
  332.     where type = 'P '
  333.             and name = 'sp_addpullsubscription_agent')
  334.     drop procedure sp_addpullsubscription_agent
  335.  
  336. if exists (select * from sysobjects
  337.     where type = 'P '
  338.             and name = 'sp_helpsubscription_properties')
  339.     drop procedure sp_helpsubscription_properties
  340.  
  341. if exists (select * from sysobjects
  342.     where type = 'P '
  343.             and name = 'sp_change_subscription_properties')
  344.     drop procedure sp_change_subscription_properties
  345.  
  346. if exists (select * from sysobjects
  347.     where type = 'P'
  348.             and name = 'sp_MSget_pullsubsagent_owner')
  349.     drop procedure sp_MSget_pullsubsagent_owner
  350.  
  351. if exists (select * from sysobjects
  352.     where type = 'P'
  353.             and name = 'sp_MSget_mergepullsubsagent_owner')
  354.     drop procedure sp_MSget_mergepullsubsagent_owner
  355.     
  356. if exists (select * from sysobjects
  357.     where type = 'P '
  358.             and name = 'sp_addmergepullsubscription_agent')
  359.     drop procedure sp_addmergepullsubscription_agent
  360.  
  361. if exists (select * from sysobjects
  362.     where type = 'P '
  363.             and name = 'sp_droppullsubscription')
  364.     drop procedure sp_droppullsubscription
  365.  
  366. if exists (select * from sysobjects
  367.     where type = 'P '
  368.             and name = 'sp_vupgrade_publisherdb')
  369.     drop procedure sp_vupgrade_publisherdb
  370.  
  371. if exists (select * from sysobjects
  372.     where type = 'P '
  373.             and name = 'sp_vupgrade_publisher')
  374.     drop procedure sp_vupgrade_publisher
  375.  
  376. if exists (select * from sysobjects
  377.     where type = 'P '
  378.             and name = 'sp_MScopyregvalue')
  379.     drop procedure sp_MScopyregvalue
  380.  
  381. if exists (select * from sysobjects
  382.     where type = 'P '
  383.             and name = 'sp_vupgrade_registry')
  384.     drop procedure sp_vupgrade_registry
  385.  
  386. -- this proc renamed
  387. if exists (select * from sysobjects
  388.     where type = 'P '
  389.             and name = 'sp_vupdate_syscol_status')
  390.     drop procedure sp_vupdate_syscol_status
  391.  
  392. if exists (select * from sysobjects
  393.     where type = 'P '
  394.             and name = 'sp_vupgrade_syscol_status')
  395.     drop procedure sp_vupgrade_syscol_status
  396.  
  397. if exists (select * from sysobjects
  398.     where type = 'P '
  399.             and name = 'sp_helppullsubscription')
  400.     drop procedure sp_helppullsubscription
  401.  
  402. if exists (select * from sysobjects
  403.     where type = 'P '
  404.             and name = 'sp_MSunmarkreplinfo')
  405.     drop procedure sp_MSunmarkreplinfo
  406.  
  407. if exists (select * from sysobjects
  408.     where type = 'P '
  409.             and name = 'sp_MSmarkreplinfo')
  410.     drop procedure sp_MSmarkreplinfo
  411.  
  412. if exists (select * from sysobjects
  413.     where type = 'P '
  414.             and name = 'sp_MSunmarkschemaobject')
  415.     drop procedure sp_MSunmarkschemaobject
  416.  
  417. if exists (select * from sysobjects
  418.     where type = 'P '
  419.             and name = 'sp_MSmarkschemaobject')
  420.     drop procedure sp_MSmarkschemaobject
  421.  
  422. if exists (select * from sysobjects
  423.     where type = 'P '
  424.             and name = 'sp_MSunmarkifneeded')
  425.     drop procedure sp_MSunmarkifneeded
  426.  
  427. if exists (select * from sysobjects
  428.         where type = 'P '
  429.                 and name = 'sp_MStable_has_unique_index')
  430.         drop procedure sp_MStable_has_unique_index
  431.  
  432. if exists (select * from sysobjects
  433.         where type = 'P '
  434.                 and name = 'sp_MSreplraiserror')
  435.         drop procedure sp_MSreplraiserror
  436.  
  437. if exists (select * from sysobjects
  438.         where type = 'P '
  439.                 and name = 'sp_check_sync_trigger')
  440.         drop procedure sp_check_sync_trigger
  441.  
  442. if exists (select * from sysobjects
  443.         where type = 'P '
  444.                 and name = 'sp_MSreplicationcompatlevel')
  445.     drop proc sp_MSreplicationcompatlevel    
  446.  
  447. if exists (select * from sysobjects
  448.         where type = 'P '
  449.                 and name = 'sp_MSgenreplnickname')
  450.     drop proc sp_MSgenreplnickname
  451.  
  452. if exists (select * from sysobjects
  453.         where type = 'P '
  454.                 and name = 'sp_MSenumallpublications')
  455.     drop proc sp_MSenumallpublications
  456.  
  457. if exists (select * from sysobjects
  458.         where type = 'P '
  459.                 and name = 'sp_MSenumallsubscriptions')
  460.     drop proc sp_MSenumallsubscriptions
  461.  
  462. if exists (select * from sysobjects
  463.         where type = 'P '
  464.                 and name = 'sp_MSenumsubscriptions')
  465.     drop proc sp_MSenumsubscriptions
  466.  
  467. if exists (select * from sysobjects
  468.         where type = 'P '
  469.                 and name = 'sp_MSenumtranpublications')
  470.     drop proc sp_MSenumtranpublications
  471.  
  472. if exists (select * from sysobjects
  473.         where type = 'P '
  474.                 and name = 'sp_MSenummergepublications')
  475.     drop proc sp_MSenummergepublications
  476.  
  477. if exists (select * from sysobjects
  478.         where type = 'P '
  479.                 and name = 'sp_MSenum3rdpartypublications')
  480.     drop proc sp_MSenum3rdpartypublications
  481.  
  482. if exists (select * from sysobjects
  483.         where type = 'P '
  484.                 and name = 'sp_MSenumthirdpartypublicationvendornames')
  485.     drop proc sp_MSenumthirdpartypublicationvendornames
  486.  
  487. if exists (select * from sysobjects
  488.                 where type = 'P' and
  489.                 name = 'sp_MSgetreplicainfo')
  490.         drop procedure sp_MSgetreplicainfo
  491.  
  492. if exists (select * from sysobjects
  493.     where type = 'P '
  494.            and name = 'sp_subscription_cleanup')
  495.      drop procedure sp_subscription_cleanup  
  496.  
  497. if exists (select * from sysobjects
  498.     where type = 'P '
  499.            and name = 'sp_mergesubscription_cleanup')
  500.      drop procedure sp_mergesubscription_cleanup  
  501.  
  502. if exists (select * from sysobjects
  503.     where type = 'P '
  504.             and name = 'sp_MSpad_command')
  505.     drop procedure sp_MSpad_command
  506.  
  507. if exists (select * from sysobjects
  508.     where type = 'P '
  509.             and name = 'sp_MSflush_command')
  510.     drop procedure sp_MSflush_command
  511.  
  512. if exists (select * from sysobjects
  513.     where type = 'P '
  514.             and name = 'sp_MSget_colinfo')
  515.     drop procedure sp_MSget_colinfo
  516.  
  517. if exists (select * from sysobjects
  518.     where type = 'P '
  519.             and name = 'sp_MSget_type')
  520.     drop procedure sp_MSget_type
  521.  
  522. if exists (select * from sysobjects
  523.     where type = 'P '
  524.             and name = 'sp_MSget_col_position')
  525.     drop procedure sp_MSget_col_position
  526.  
  527. if exists (select * from sysobjects
  528.     where type = 'P '
  529.             and name = 'sp_MSget_map_position')
  530.     drop procedure sp_MSget_map_position
  531.  
  532. if exists (select * from sysobjects
  533.     where type = 'P '
  534.             and name = 'sp_MSscript_where_clause')
  535.     drop procedure sp_MSscript_where_clause
  536.  
  537. if exists (select * from sysobjects
  538.     where type = 'P '
  539.             and name = 'sp_MSscript_params')
  540.     drop procedure sp_MSscript_params
  541.  
  542. if exists (select * from sysobjects
  543.     where type = 'P '
  544.             and name = 'sp_MSscript_procbodystart')
  545.     drop procedure sp_MSscript_procbodystart
  546.  
  547. if exists (select * from sysobjects
  548.     where type = 'P '
  549.             and name = 'sp_MSscript_begintrig1')
  550.     drop procedure sp_MSscript_begintrig1
  551.  
  552. if exists (select * from sysobjects
  553.     where type = 'P '
  554.             and name = 'sp_MSscript_begintrig2')
  555.     drop procedure sp_MSscript_begintrig2
  556.  
  557. if exists (select * from sysobjects
  558.     where type = 'P '
  559.             and name = 'sp_MSscript_endtrig')
  560.     drop procedure sp_MSscript_endtrig
  561.  
  562. if exists (select * from sysobjects
  563.     where type = 'P '
  564.             and name = 'sp_MSscript_trigger_variables')
  565.     drop procedure sp_MSscript_trigger_variables
  566.  
  567. if exists (select * from sysobjects
  568.     where type = 'P '
  569.             and name = 'sp_MSscript_trigger_assignment')
  570.     drop procedure sp_MSscript_trigger_assignment
  571.  
  572. if exists (select * from sysobjects
  573.     where type = 'P '
  574.             and name = 'sp_validatemergepullsubscription')
  575.     drop procedure sp_validatemergepullsubscription
  576.  
  577. if exists (select * from sysobjects
  578.     where type = 'P '
  579.             and name = 'sp_MSscript_trigger_fetch_statement')
  580.     drop procedure sp_MSscript_trigger_fetch_statement
  581.  
  582. if exists (select * from sysobjects
  583.     where type = 'P '
  584.             and name = 'sp_MSscript_trigger_exec_rpc')
  585.     drop procedure sp_MSscript_trigger_exec_rpc
  586.  
  587. if exists (select * from sysobjects
  588.     where type = 'P '
  589.             and name = 'sp_MSscript_trigger_update_checks')
  590.     drop procedure sp_MSscript_trigger_update_checks
  591.  
  592. if exists (select * from sysobjects
  593.     where type = 'P '
  594.             and name = 'sp_MSscript_trigger_updates')
  595.     drop procedure sp_MSscript_trigger_updates
  596.  
  597. if exists (select * from sysobjects
  598.     where type = 'P '
  599.             and name = 'sp_MSscript_singlerow_trigger')
  600.     drop procedure sp_MSscript_singlerow_trigger
  601.  
  602. if exists (select * from sysobjects
  603.     where type = 'P '
  604.             and name = 'sp_MSscript_multirow_trigger')
  605.     drop procedure sp_MSscript_multirow_trigger
  606.  
  607. if exists (select * from sysobjects
  608.     where type = 'P '
  609.             and name = 'sp_MSscript_sync_ins_trig')
  610.     drop procedure sp_MSscript_sync_ins_trig
  611.  
  612. if exists (select * from sysobjects
  613.     where type = 'P '
  614.             and name = 'sp_MSscript_sync_upd_trig')
  615.     drop procedure sp_MSscript_sync_upd_trig
  616.  
  617. if exists (select * from sysobjects
  618.     where type = 'P '
  619.             and name = 'sp_MSscript_sync_del_trig')
  620.     drop procedure sp_MSscript_sync_del_trig
  621.  
  622. if exists (select * from sysobjects
  623.     where type = 'P '
  624.             and name = 'sp_MSget_synctran_column')
  625.     drop procedure sp_MSget_synctran_column
  626.  
  627. if exists (select * from sysobjects
  628.     where type = 'P '
  629.             and name = 'sp_check_for_sync_trigger')
  630.     drop procedure sp_check_for_sync_trigger
  631.  
  632. if exists (select * from sysobjects
  633.     where type = 'P '
  634.             and name = 'sp_addqueued_artinfo')
  635.     drop procedure sp_addqueued_artinfo    
  636.  
  637. if exists (select * from sysobjects
  638.     where type = 'P '
  639.             and name = 'sp_addsynctriggers')
  640.     drop procedure sp_addsynctriggers
  641.  
  642. if exists (select * from sysobjects
  643.     where type = 'P '
  644.             and name = 'sp_setreplfailovermode')
  645.     drop procedure sp_setreplfailovermode
  646.  
  647. if exists (select * from sysobjects
  648.     where type = 'P '
  649.             and name = 'sp_helpreplfailovermode')
  650.     drop procedure sp_helpreplfailovermode
  651.  
  652. if exists (select * from sysobjects
  653.         where type = 'P '
  654.             and name = 'sp_helpreplicationdboption')
  655.     drop procedure sp_helpreplicationdboption
  656.  
  657. if exists (select * from sysobjects
  658.         where type = 'P' and name = 'sp_MSgetreplnick')
  659.     drop procedure sp_MSgetreplnick
  660.         
  661. if exists (select * from sysobjects
  662.         where type = 'P' and name = 'sp_MStestbit')        
  663.     drop procedure sp_MStestbit
  664.         
  665. if exists (select * from sysobjects
  666.         where type = 'P' and name = 'sp_MSsetbit')
  667.     drop procedure sp_MSsetbit
  668.         
  669.         
  670. if exists (select * from sysobjects
  671.         where type = 'P' and name = 'sp_MSinsertcontents')
  672.     drop procedure sp_MSinsertcontents
  673.         
  674. if exists (select * from sysobjects
  675.         where type = 'P' and name = 'sp_MSupdatecontents')
  676.     drop procedure sp_MSupdatecontents
  677.             
  678. if exists (select * from sysobjects
  679.         where type = 'P' and name = 'sp_MSdeletecontents')
  680.     drop procedure sp_MSdeletecontents
  681.  
  682. if exists (select * from sysobjects
  683.         where type = 'P '
  684.             and name = 'sp_MSadd_repl_job')
  685.     drop procedure sp_MSadd_repl_job
  686.  
  687. IF EXISTS (select * from sysobjects where
  688.    name = 'sp_MScheck_agent_instance' and type = 'P')
  689.       DROP PROCEDURE sp_MScheck_agent_instance
  690.  
  691. IF EXISTS (select * from sysobjects where
  692.    name = 'sp_MSenum_replsqlqueues' and type = 'P')
  693.       DROP PROCEDURE sp_MSenum_replsqlqueues
  694.  
  695. IF EXISTS (select * from sysobjects where
  696.    name = 'sp_MSenum_replqueues' and type = 'P')
  697.       DROP PROCEDURE sp_MSenum_replqueues
  698.  
  699. if exists (select * from sysobjects
  700.         where name = 'xp_mergexpusage')
  701.     execute dbo.sp_dropextendedproc 'xp_mergexpusage'
  702.  
  703. if exists (select * from sysobjects 
  704.         where name = 'sp_get_distributor' 
  705.                 and type = 'P')
  706.       drop procedure sp_get_distributor
  707.  
  708. if exists (select * from sysobjects 
  709.         where name = 'sp_MSrepl_addrolemember' 
  710.                 and type = 'P')
  711.       drop procedure sp_MSrepl_addrolemember
  712.  
  713. if exists (select * from sysobjects 
  714.         where name = 'sp_MSrepl_droprolemember' 
  715.                 and type = 'P')
  716.       drop procedure sp_MSrepl_droprolemember
  717.  
  718. if exists (select * from sysobjects 
  719.         where name = 'sp_table_validation' 
  720.                 and type = 'P')
  721.       drop procedure sp_table_validation
  722.  
  723. if exists (select * from sysobjects 
  724.         where name = 'sp_MScreate_sub_tables' 
  725.                 and type = 'P')
  726.       drop procedure sp_MScreate_sub_tables
  727. go
  728.  
  729. if exists (select * from sysobjects 
  730.         where name = 'sp_MSupdate_mqserver_subdb' 
  731.                 and type = 'P')
  732.       drop procedure sp_MSupdate_mqserver_subdb
  733.  
  734. if exists (select * from sysobjects 
  735.         where name = 'sp_removedbreplication' 
  736.                 and type = 'P')
  737.       drop procedure sp_removedbreplication
  738.  
  739. if exists (select * from sysobjects 
  740.         where name = 'sp_MSBumpupCompLevel' 
  741.                 and type = 'P')
  742.       drop procedure sp_MSBumpupCompLevel
  743.  
  744. if exists (select * from sysobjects 
  745.         where name = 'sp_cleanupdbreplication' 
  746.                 and type = 'P')
  747.       drop procedure sp_cleanupdbreplication
  748.  
  749. if exists (select * from sysobjects 
  750.         where name = 'sp_removesrvreplication' 
  751.                 and type = 'P')
  752.       drop procedure sp_removesrvreplication
  753.  
  754. if exists (select * from sysobjects 
  755.         where name = 'sp_vupgrade_subscription_databases' 
  756.                 and type = 'P')
  757.       drop procedure sp_vupgrade_subscription_databases
  758.  
  759. if exists (select * from sysobjects 
  760.         where name = 'sp_vupgrade_MSsubscription_properties' 
  761.                 and type = 'P')
  762.       drop procedure sp_vupgrade_MSsubscription_properties
  763.  
  764. if exists (select * from sysobjects 
  765.         where name = 'sp_vupgrade_mergetables' 
  766.                 and type = 'P')
  767.       drop procedure sp_vupgrade_mergetables
  768.  
  769. if exists (select * from sysobjects 
  770.         where name = 'sp_vupgrade_subpass' 
  771.                 and type = 'P')
  772.       drop procedure sp_vupgrade_subpass
  773.  
  774. if exists (select * from sysobjects 
  775.         where name = 'sp_vupgrade_subscription_tables' 
  776.                 and type = 'P')
  777.       drop procedure sp_vupgrade_subscription_tables
  778.  
  779. if exists (select * from sysobjects 
  780.         where name = 'sp_vupgrade_replication' 
  781.                 and type = 'P')
  782.       drop procedure sp_vupgrade_replication
  783.  
  784. if exists (select * from sysobjects 
  785.         where name = 'sp_vupgrade_distdb' 
  786.                 and type = 'P')
  787.       drop procedure sp_vupgrade_distdb
  788.  
  789. if exists (select * from sysobjects 
  790.         where name = 'sp_vupgrade_replmsdb' 
  791.                 and type = 'P')
  792.       drop procedure sp_vupgrade_replmsdb
  793.  
  794. if exists (select * from sysobjects 
  795.         where name = 'sp_restoredbreplication' 
  796.                 and type = 'P')
  797.       drop procedure sp_restoredbreplication
  798.  
  799. if exists (select * from sysobjects 
  800.         where name = 'sp_MSget_publisher_rpc' 
  801.                 and type = 'P')
  802.       drop procedure sp_MSget_publisher_rpc
  803.  
  804. if exists (select * from sysobjects 
  805.         where name = 'sp_link_publication' 
  806.                 and type = 'P')
  807.       drop procedure sp_link_publication
  808.  
  809. if exists (select * from sysobjects 
  810.         where name = 'sp_MS_replication_installed' 
  811.                 and type = 'P')
  812.       drop procedure sp_MS_replication_installed
  813.  
  814. if exists (select * from sysobjects 
  815.         where name = 'sp_MSunc_to_drive' 
  816.                 and type = 'P')
  817.       drop procedure sp_MSunc_to_drive
  818.  
  819. if exists (select * from sysobjects 
  820.         where name = 'sp_MSdrop_object' 
  821.                 and type = 'P')
  822.       drop procedure sp_MSdrop_object
  823.  
  824. if exists (select * from sysobjects 
  825.         where name = 'sp_MSregistersubscription' 
  826.                 and type = 'P')
  827.       drop procedure sp_MSregistersubscription
  828.  
  829. if exists (select * from sysobjects 
  830.         where name = 'sp_MSunregistersubscription' 
  831.                 and type = 'P')
  832.       drop procedure sp_MSunregistersubscription
  833.  
  834. if exists (select * from sysobjects 
  835.         where name = 'sp_MSsubscription_enabled_for_syncmgr' 
  836.                 and type = 'P')
  837.       drop procedure sp_MSsubscription_enabled_for_syncmgr
  838.  
  839. if exists (select * from sysobjects 
  840.         where name = 'sp_MSrepl_linkedservers_rowset' 
  841.                 and type = 'P')
  842.       drop procedure sp_MSrepl_linkedservers_rowset
  843.  
  844. if exists (select * from sysobjects 
  845.         where name = 'sp_MSrepl_isdbowner' 
  846.                 and type = 'P')
  847.       drop procedure sp_MSrepl_isdbowner
  848.  
  849. if exists (select * from sysobjects 
  850.         where name = 'sp_MSget_qualified_name' 
  851.                 and type = 'P')
  852.       drop procedure sp_MSget_qualified_name
  853.  
  854. if exists (select * from sysobjects 
  855.         where name = 'sp_MSscript_pkvar_assignment' 
  856.                 and type = 'P')
  857.       drop procedure sp_MSscript_pkvar_assignment
  858. go
  859.  
  860. if exists (select * from sysobjects 
  861.         where name = 'sp_MSget_jobstate' 
  862.                 and type = 'P')
  863.       drop procedure sp_MSget_jobstate
  864.  
  865. go
  866.  
  867. if exists (select * from sysobjects 
  868.         where name = 'sp_browsemergesnapshotfolder' 
  869.                 and type = 'P')
  870.       drop procedure sp_browsemergesnapshotfolder
  871. go
  872.  
  873. if exists (select * from sysobjects 
  874.         where name = 'sp_browsesnapshotfolder' 
  875.                 and type = 'P')
  876.       drop procedure sp_browsesnapshotfolder
  877. go
  878.  
  879. if exists (select * from sysobjects 
  880.         where name = 'sp_MScopysnapshot' 
  881.                 and type = 'P')
  882.       drop procedure sp_MScopysnapshot
  883. go
  884.  
  885. if exists (select * from sysobjects 
  886.         where name = 'sp_copymergesnapshot' 
  887.                 and type = 'P')
  888.       drop procedure sp_copymergesnapshot
  889. go
  890.  
  891. if exists (select * from sysobjects 
  892.         where name = 'sp_copysnapshot' 
  893.                 and type = 'P')
  894.       drop procedure sp_copysnapshot
  895. go
  896.  
  897. if exists (select * from sysobjects 
  898.         where name = 'sp_getsubscriptiondtspackagename' 
  899.                 and type = 'P')
  900.       drop procedure sp_getsubscriptiondtspackagename
  901. go
  902.  
  903.  
  904. if exists (select * from sysobjects
  905.     where type = 'P '
  906.             and name = 'sp_MSget_publication_from_taskname')
  907.     drop procedure sp_MSget_publication_from_taskname
  908. go
  909.  
  910. if exists (select * from sysobjects
  911.     where type = 'P '
  912.             and name = 'sp_MSrepl_check_server')
  913.     drop procedure sp_MSrepl_check_server
  914. go
  915.  
  916. if exists (select * from sysobjects
  917.     where type = 'P '
  918.             and name = 'sp_MSreset_synctran_bit')
  919.     drop procedure sp_MSreset_synctran_bit
  920. go
  921.  
  922. if exists (select * from sysobjects
  923.     where type = 'P '
  924.             and name = 'sp_MSreset_queue')
  925.     drop procedure sp_MSreset_queue
  926. go
  927.  
  928. if exists (select * from sysobjects
  929.     where type = 'P '
  930.             and name = 'sp_MSreset_queued_reinit')
  931.     drop procedure sp_MSreset_queued_reinit
  932. go
  933.  
  934. if exists (select * from sysobjects
  935.     where type = 'P '
  936.             and name = 'sp_MSinit_subscription_agent')
  937.     drop procedure sp_MSinit_subscription_agent
  938. go
  939.  
  940. if exists (select * from sysobjects
  941.     where type = 'P '
  942.             and name = 'sp_MSupdatelastsyncinfo')
  943.     drop procedure sp_MSupdatelastsyncinfo
  944. go
  945.  
  946. if exists (select * from sysobjects
  947.     where type = 'P '
  948.             and name = 'sp_MSget_attach_state')
  949.     drop procedure sp_MSget_attach_state
  950. go
  951.  
  952. if exists (select * from sysobjects
  953.     where type = 'P '
  954.             and name = 'sp_MSreset_attach_state')
  955.     drop procedure sp_MSreset_attach_state
  956. go
  957.  
  958. if exists (select * from sysobjects
  959.     where type = 'P'
  960.             and name = 'sp_replicationdboption')
  961.     drop procedure sp_replicationdboption
  962.  
  963. if exists (select * from sysobjects
  964.     where type = 'P '
  965.             and name = 'sp_MSset_subscription_properties')
  966.     drop procedure sp_MSset_subscription_properties
  967. go
  968.  
  969. if exists (select * from sysobjects
  970.     where type = 'P '
  971.             and name = 'sp_MSset_sub_guid')
  972.     drop procedure sp_MSset_sub_guid
  973. go
  974.  
  975. if exists (select * from sysobjects
  976.     where type = 'P' and name = 'sp_populateqtraninfo')
  977. drop procedure sp_populateqtraninfo
  978. go
  979.  
  980. if exists (select * from sysobjects
  981.     where type = 'P '
  982.             and name = 'sp_MSscript_trigger_version_updates')
  983.     drop procedure sp_MSscript_trigger_version_updates
  984. go
  985.  
  986. if exists (select * from sysobjects
  987.     where type = 'P '
  988.             and name = 'sp_MSget_load_hint')
  989.     drop procedure sp_MSget_load_hint
  990. go
  991.  
  992. if exists (select * from sysobjects
  993.     where type in ('P ') 
  994.         and name = 'sp_repladdcolumn')
  995.     drop procedure sp_repladdcolumn
  996. go
  997. if exists (select * from sysobjects
  998.     where type in ('P ') 
  999.         and name = 'sp_MSverifytranfilter')
  1000.     drop procedure sp_MSverifytranfilter
  1001. go
  1002.  
  1003. if exists (select * from sysobjects
  1004.     where type in ('P ') 
  1005.         and name = 'sp_repldropcolumn')
  1006.     drop procedure sp_repldropcolumn
  1007. go
  1008.  
  1009. if exists (select * from sysobjects
  1010.     where type = 'P '
  1011.             and name = 'sp_MSrepl_validate_dts_package')
  1012.     drop procedure sp_MSrepl_validate_dts_package
  1013. go
  1014.  
  1015. if exists (select * from sysobjects
  1016.      where type = 'P '
  1017.             and name = 'sp_MSagent_access_check')
  1018.      drop procedure sp_MSagent_access_check
  1019. go
  1020.  
  1021. if exists (select * from sysobjects
  1022.      where type = 'P '
  1023.             and name = 'sp_enableagentoffload')
  1024.      drop procedure sp_enableagentoffload
  1025. go
  1026.  
  1027. if exists (select * from sysobjects
  1028.      where type = 'P '
  1029.             and name = 'sp_disableagentoffload')
  1030.      drop procedure sp_disableagentoffload
  1031. go
  1032.  
  1033. if exists (select * from sysobjects
  1034.      where type = 'P '
  1035.             and name = 'sp_getagentoffloadinfo')
  1036.      drop procedure sp_getagentoffloadinfo
  1037. go
  1038.  
  1039. if exists (select * from sysobjects
  1040.      where type = 'P '
  1041.             and name = 'sp_copysubscription')
  1042.      drop procedure sp_copysubscription
  1043. go
  1044.  
  1045. if exists (select * from sysobjects
  1046.      where type = 'P '
  1047.             and name = 'sp_attachsubscription')
  1048.      drop procedure sp_attachsubscription
  1049. go
  1050.  
  1051. if exists (select * from sysobjects
  1052.      where type = 'P '
  1053.             and name = 'sp_MSget_file_existence')
  1054.      drop procedure sp_MSget_file_existence
  1055. go
  1056.  
  1057. if exists (select * from sysobjects
  1058.      where type = 'P '
  1059.             and name = 'sp_MSrestore_sub')
  1060.      drop procedure sp_MSrestore_sub
  1061. go
  1062.  
  1063. if exists (select * from sysobjects
  1064.      where type = 'P '
  1065.             and name = 'sp_MSrestore_sub_tran')
  1066.      drop procedure sp_MSrestore_sub_tran
  1067. go
  1068.  
  1069. if exists (select * from sysobjects
  1070.      where type = 'P '
  1071.             and name = 'sp_MSrestore_sub_merge')
  1072.      drop procedure sp_MSrestore_sub_merge
  1073. go
  1074.  
  1075. if exists (select * from sysobjects
  1076.      where type = 'P'
  1077.             and name = 'sp_MSsub_check_identity')
  1078.      drop procedure sp_MSsub_check_identity
  1079. go
  1080.  
  1081. if exists (select * from sysobjects
  1082.      where type = 'P'
  1083.             and name = 'sp_MSsub_cleanup_orphans')
  1084.      drop procedure sp_MSsub_cleanup_orphans
  1085. go
  1086.  
  1087. if exists (select * from sysobjects
  1088.      where type = 'P'
  1089.             and name = 'sp_MSsub_cleanup_prop_table')
  1090.      drop procedure sp_MSsub_cleanup_prop_table
  1091. go
  1092.  
  1093. if exists (select * from sysobjects
  1094.      where type = 'P'
  1095.             and name = 'sp_MSreseed')
  1096.      drop procedure sp_MSreseed
  1097. go
  1098.  
  1099. if exists (select * from sysobjects
  1100.      where type = 'P'
  1101.             and name = 'sp_MSsub_set_identity')
  1102.      drop procedure sp_MSsub_set_identity
  1103. go
  1104.  
  1105. if exists (select * from sysobjects
  1106.      where type = 'P '
  1107.             and name = 'sp_MSprepare_sub_for_detach')
  1108.      drop procedure sp_MSprepare_sub_for_detach
  1109. go
  1110.  
  1111. if exists (select * from sysobjects
  1112.      where type = 'P '
  1113.             and name = 'sp_MSadd_compensating_cmd')
  1114.      drop procedure sp_MSadd_compensating_cmd
  1115. go
  1116.  
  1117. if exists (select * from sysobjects
  1118.      where type = 'FN'
  1119.             and name = 'fn_varbintohexstr')
  1120.      drop function fn_varbintohexstr
  1121. go
  1122.  
  1123. if exists (select * from sysobjects
  1124.      where type = 'FN'
  1125.             and name = 'fn_varbintohexsubstring')
  1126.      drop function fn_varbintohexsubstring
  1127. go
  1128.  
  1129. if exists ( select * from sysobjects 
  1130.     where type = 'FN' 
  1131.             and name = 'fn_MSsharedversion' )
  1132.     drop function fn_MSsharedversion
  1133. go
  1134.  
  1135. if exists ( select * from sysobjects 
  1136.     where type = 'P' 
  1137.             and name = 'sp_MSgettools_path' )
  1138.     drop procedure sp_MSgettools_path
  1139. go
  1140.  
  1141. if exists ( select * from sysobjects 
  1142.     where type = 'P' 
  1143.             and name = 'sp_MSget_setup_paths' )
  1144.     drop procedure sp_MSget_setup_paths
  1145. go
  1146.  
  1147. if exists (select * from sysobjects where
  1148.    name = 'sp_MSaddoffloadparameter' and type = 'P')
  1149.       drop procedure sp_MSaddoffloadparameter
  1150.  
  1151. if exists (select * from sysobjects where
  1152.    name = 'sp_MSremoveoffloadparameter' and type = 'P')
  1153.       drop procedure sp_MSremoveoffloadparameter 
  1154. go
  1155.  
  1156. if exists (select * from sysobjects where
  1157.    name = 'sp_MSsendtosqlqueue' and type = 'P')
  1158.       drop procedure sp_MSsendtosqlqueue 
  1159. go
  1160.  
  1161. if exists (select * from sysobjects
  1162.     where type = 'P'
  1163.            and name = 'sp_MSdropfkreferencingarticle')
  1164.     drop procedure sp_MSdropfkreferencingarticle
  1165. go
  1166.  
  1167. if exists (select * from sysobjects
  1168.      where type = 'FN'
  1169.             and name = 'fn_MSgensqescstr')
  1170.      drop function fn_MSgensqescstr
  1171. go
  1172.  
  1173. if exists (select * from sysobjects
  1174.     where type = 'P'
  1175.             and name = 'sp_MSestimatesnapshotworkload')
  1176.     drop procedure sp_MSestimatesnapshotworkload
  1177. go
  1178.  
  1179. if exists (select * from sysobjects
  1180.     where type = 'P'
  1181.             and name = 'sp_MSestimatemergesnapshotworkload')
  1182.     drop procedure sp_MSestimatemergesnapshotworkload
  1183. go
  1184.  
  1185. if exists (select * from sysobjects
  1186.     where type = 'P'
  1187.             and name = 'sp_resyncmergesubscription')
  1188.     drop procedure sp_resyncmergesubscription
  1189. go
  1190.  
  1191. if exists (select * from sysobjects
  1192.     where type = 'P'
  1193.             and name = 'sp_MSinstance_qv')
  1194.     drop procedure sp_MSinstance_qv
  1195.  
  1196. if exists (select * from sysobjects
  1197.     where type = 'P'
  1198.             and name = 'sp_MSget_shared_agent')
  1199.     drop procedure sp_MSget_shared_agent
  1200.  
  1201.  
  1202. if exists (select * from sysobjects 
  1203.     where type = 'P'
  1204.             and name = 'sp_MSgetlastupdatedtime')
  1205.     drop procedure sp_MSgetlastupdatedtime
  1206.     
  1207. if exists (select * from sysobjects
  1208.     where type = 'P'
  1209.             and name = 'sp_MSgettranlastupdatedtime')
  1210.     drop procedure sp_MSgettranlastupdatedtime
  1211.  
  1212.  
  1213. if exists (select * from sysobjects
  1214.     where type = 'P'
  1215.             and name = 'sp_MSgetmergelastupdatedtime')
  1216.     drop procedure sp_MSgetmergelastupdatedtime
  1217. go
  1218.  
  1219. if exists (select * from sysobjects
  1220.     where type = 'P'
  1221.             and name = 'sp_MSrepl_backup_start')
  1222.     drop procedure sp_MSrepl_backup_start
  1223. go
  1224.  
  1225. if exists (select * from sysobjects
  1226.     where type = 'P'
  1227.             and name = 'sp_MSrepl_backup_complete')
  1228.     drop procedure sp_MSrepl_backup_complete
  1229. go
  1230.  
  1231. if exists (select * from sysobjects
  1232.     where type = 'P'
  1233.             and name = 'sp_MSreplcheckoffloadserver')
  1234.     drop procedure sp_MSreplcheckoffloadserver
  1235.  
  1236. if exists ( select * from sysobjects
  1237.     where type = 'P ' and name = 'sp_addscriptexec' )
  1238.     drop procedure sp_addscriptexec    
  1239.  
  1240. if exists ( select * from sysobjects
  1241.     where type = 'P ' and name = 'sp_MSmergeupdatelastsyncinfo' )
  1242.     drop procedure sp_MSmergeupdatelastsyncinfo    
  1243. go
  1244.  
  1245. if exists ( select * from sysobjects
  1246.     where type = 'P ' and name = 'sp_MSdroparticleconstraints' )
  1247.     drop procedure sp_MSdroparticleconstraints
  1248.  
  1249. go
  1250.  
  1251. if exists ( select * from sysobjects
  1252.     where type = 'FN'
  1253.     and name = 'fn_replquotename' )
  1254.     drop function system_function_schema.fn_replquotename
  1255.  
  1256. if exists ( select * from sysobjects
  1257.     where type = 'FN'
  1258.     and name = 'fn_repladjustcolumnmap' )
  1259.     drop function system_function_schema.fn_repladjustcolumnmap
  1260.  
  1261. if exists ( select * from sysobjects
  1262.     where type = 'FN'
  1263.     and name = 'fn_generateparameterpattern' )
  1264.     drop function system_function_schema.fn_generateparameterpattern
  1265.  
  1266. if exists ( select * from sysobjects
  1267.     where type = 'FN'
  1268.         and name = 'fn_removeparameterwithargument' )
  1269.     drop function system_function_schema.fn_removeparameterwithargument
  1270.  
  1271. if exists ( select * from sysobjects
  1272.     where type = 'FN'
  1273.     and name = 'fn_updateparameterwithargument' )
  1274.     drop function system_function_schema.fn_updateparameterwithargument
  1275.  
  1276. if exists ( select * from sysobjects
  1277.     where type = 'FN'
  1278.     and name = 'fn_skipparameterargument' )
  1279.     drop function system_function_schema.fn_skipparameterargument
  1280.  
  1281. if exists ( select * from sysobjects
  1282.     where type = 'FN'
  1283.         and name = 'fn_chariswhitespace' )
  1284.     drop function system_function_schema.fn_chariswhitespace
  1285.  
  1286. if exists ( select * from sysobjects
  1287.     where type = 'FN'
  1288.         and name = 'fn_replmakestringliteral' )
  1289.     drop function system_function_schema.fn_replmakestringliteral
  1290.  
  1291. if exists ( select * from sysobjects
  1292.     where type = 'FN'
  1293.     and name = 'fn_replprepadbinary8' )
  1294.    drop function system_function_schema.fn_replprepadbinary8
  1295.  
  1296. if exists ( select * from sysobjects
  1297.     where type = 'FN'
  1298.     and name = 'fn_replgetbinary8lodword' )
  1299.     drop function system_function_schema.fn_replgetbinary8lodword
  1300.  
  1301. if exists ( select * from sysobjects
  1302.     where type = 'P'
  1303.     and name = 'sp_MSacquireserverresourcefordynamicsnapshot')
  1304.     drop procedure sp_MSacquireserverresourcefordynamicsnapshot
  1305. if exists ( select * from sysobjects
  1306.     where type = 'FN'
  1307.     and name = 'fn_repluniquename' )
  1308.     drop function system_function_schema.fn_repluniquename
  1309.  
  1310. if exists (select * from sysobjects 
  1311.     where type = 'P'
  1312.             and name = 'sp_MSsetcontext_replagent')
  1313.     drop procedure sp_MSsetcontext_replagent
  1314.  
  1315. if exists ( select * from sysobjects
  1316.     where type = 'FN'
  1317.     and name = 'fn_isreplmergeagent' )
  1318.     drop function dbo.fn_isreplmergeagent 
  1319.  
  1320. if exists (select * from sysobjects 
  1321.     where type = 'FN'
  1322.     and name = N'fn_replinttobitstring' )
  1323.     drop function system_function_schema.fn_replinttobitstring
  1324.  
  1325. if exists (select * from sysobjects
  1326.     where type = 'FN'
  1327.     and name = N'fn_replbitstringtoint' )
  1328.     drop function system_function_schema.fn_replbitstringtoint
  1329.  
  1330. if exists (select * from sysobjects
  1331.     where type = 'FN'
  1332.     and name = N'fn_replrotr' )
  1333.     drop function system_function_schema.fn_replrotr
  1334.  
  1335. if exists (select * from sysobjects
  1336.     where type = 'FN'
  1337.     and name = N'fn_replgenerateshorterfilenameprefix' )
  1338.     drop function system_function_schema.fn_replgenerateshorterfilenameprefix
  1339.  
  1340. if exists (select * from sysobjects 
  1341.     where type = 'FN'
  1342.     and name = N'fn_replcomposepublicationsnapshotfolder' )
  1343.     drop function system_function_schema.fn_replcomposepublicationsnapshotfolder
  1344.  
  1345. if exists (select * from sysobjects
  1346.     where type = 'FN'
  1347.     and name = N'fn_repltrimleadingzerosinhexstr' )
  1348.     drop function system_function_schema.fn_repltrimleadingzerosinhexstr
  1349.  
  1350. if exists (select * from sysobjects
  1351.     where type = 'FN'
  1352.     and name = N'fn_escapecmdshellsymbols' )
  1353.     drop function system_function_schema.fn_escapecmdshellsymbols
  1354.  
  1355. if exists (select * from sysobjects
  1356.     where type = 'FN'
  1357.     and name = N'fn_escapecmdshellsymbolsremovequotes' )
  1358.     drop function system_function_schema.fn_escapecmdshellsymbolsremovequotes
  1359.  
  1360. if exists (select * from sysobjects
  1361.     where type = 'P '
  1362.         and name = 'sp_MSispulldistributionjobnamegenerated')
  1363.     drop procedure dbo.sp_MSispulldistributionjobnamegenerated
  1364.  
  1365. if exists (select * from sysobjects
  1366.     where type = 'P '
  1367.         and name = 'sp_MSispullmergejobnamegenerated')
  1368.     drop procedure dbo.sp_MSispullmergejobnamegenerated
  1369. go
  1370.  
  1371. if exists (select * from sysobjects
  1372.     where type = 'P'
  1373.        and name = 'sp_createmergepalrole')
  1374.     drop procedure sp_createmergepalrole
  1375. go
  1376.  
  1377. if exists (select * from sysobjects
  1378.     where type = 'P'
  1379.        and name = 'sp_MSrepl_FixPALRole')
  1380.     drop procedure sp_MSrepl_FixPALRole
  1381. go
  1382.  
  1383. if exists (select * from sysobjects
  1384.             where  type = 'X' and name = 'xp_execresultset')
  1385. begin
  1386.     execute dbo.sp_dropextendedproc 'xp_execresultset'
  1387. end
  1388. go
  1389. if exists (select * from sysobjects
  1390.             where type = 'P' and name = 'xp_execresultset')
  1391. begin
  1392.     drop procedure dbo.xp_execresultset
  1393. end
  1394. go
  1395. if exists (select * from sysobjects
  1396.             where type = 'P' and name = 'sp_execresultset')
  1397. begin
  1398.     drop procedure dbo.sp_execresultset
  1399. end
  1400. go
  1401. use master
  1402. go
  1403.  
  1404. IF EXISTS ( SELECT * FROM sysobjects WHERE uid = USER_ID('system_function_schema') 
  1405.     AND name = 'fn_serverid' )
  1406. DROP FUNCTION system_function_schema.fn_serverid
  1407. go
  1408.  
  1409. sp_addextendedproc 'xp_mergexpusage', 'xprepl.dll'
  1410. go
  1411.  
  1412. grant exec on xp_mergexpusage to public
  1413. go
  1414.  
  1415. if exists (select * from sysobjects
  1416.         where name = 'xp_showlineage')
  1417.     execute dbo.sp_dropextendedproc 'xp_showlineage'
  1418. go
  1419.  
  1420. sp_addextendedproc 'xp_showlineage', 'xprepl.dll'
  1421. go
  1422.  
  1423. grant exec on xp_showlineage to public
  1424. go
  1425.  
  1426. if exists (select * from sysobjects
  1427.         where name = 'xp_mergelineages' and xtype = 'X')
  1428.     execute dbo.sp_dropextendedproc 'xp_mergelineages'
  1429. go
  1430.  
  1431. sp_addextendedproc 'xp_mergelineages', 'xprepl.dll'
  1432. go
  1433.  
  1434. if exists (select * from sysobjects    where name = 'xp_updatelineage' and xtype = 'X')
  1435.     execute dbo.sp_dropextendedproc 'xp_updatelineage'
  1436. go
  1437.  
  1438. if exists (select * from sysobjects
  1439.         where name = 'xp_mapdown_bitmap')
  1440.     execute dbo.sp_dropextendedproc 'xp_mapdown_bitmap'
  1441. go
  1442.  
  1443. sp_addextendedproc 'xp_mapdown_bitmap', 'xprepl.dll'
  1444. go
  1445.  
  1446. grant exec on xp_mapdown_bitmap to public
  1447. go
  1448.  
  1449. if exists (select * from sysobjects
  1450.         where name = 'xp_ORbitmap')
  1451.     execute dbo.sp_dropextendedproc 'xp_ORbitmap'
  1452. go
  1453. sp_addextendedproc 'xp_ORbitmap', 'xprepl.dll'
  1454. go
  1455.  
  1456. if exists (select * from sysobjects
  1457.         where name = 'xp_proxiedmetadata')
  1458.     execute dbo.sp_dropextendedproc 'xp_proxiedmetadata'
  1459. go
  1460.  
  1461. sp_addextendedproc 'xp_proxiedmetadata', 'xprepl.dll'
  1462. go
  1463.  
  1464. if exists (select * from sysobjects    where name = 'xp_initcolvs' and xtype = 'X')
  1465.     execute dbo.sp_dropextendedproc 'xp_initcolvs'
  1466. go
  1467.  
  1468. if exists (select * from sysobjects    where name = 'xp_updatecolvbm' and xtype = 'X')
  1469.     execute dbo.sp_dropextendedproc 'xp_updatecolvbm'
  1470. go
  1471.  
  1472. if exists (select * from sysobjects
  1473.         where name = 'xp_showcolv')
  1474.     execute dbo.sp_dropextendedproc 'xp_showcolv'
  1475. go
  1476.  
  1477. sp_addextendedproc 'xp_showcolv', 'xprepl.dll'
  1478. go
  1479.  
  1480. grant exec on xp_showcolv to public
  1481. go
  1482.  
  1483. if exists (select * from sysobjects
  1484.         where name = 'xp_varbintohexstr')
  1485.     execute dbo.sp_dropextendedproc 'xp_varbintohexstr'
  1486. go
  1487.  
  1488. sp_addextendedproc 'xp_varbintohexstr', 'xprepl.dll'
  1489. go
  1490.  
  1491. if exists (select * from sysobjects
  1492.         where name = 'xp_intersectbitmaps')
  1493.     execute dbo.sp_dropextendedproc 'xp_intersectbitmaps'
  1494. go
  1495.  
  1496. if exists (select * from sysobjects
  1497.         where name = 'xp_displayparamstmt')
  1498.     execute dbo.sp_dropextendedproc 'xp_displayparamstmt'
  1499. go
  1500.  
  1501. sp_addextendedproc 'xp_displayparamstmt', 'xprepl.dll'
  1502. go
  1503.  
  1504. if exists (select * from sysobjects
  1505.         where name = 'xp_printstatements')
  1506.     execute dbo.sp_dropextendedproc 'xp_printstatements'
  1507. go
  1508.  
  1509. sp_addextendedproc 'xp_printstatements', 'xprepl.dll'
  1510. go
  1511.  
  1512. if exists (select * from sysobjects
  1513.         where name = 'xp_createqueue')
  1514.     execute dbo.sp_dropextendedproc 'xp_createqueue'
  1515. go
  1516.  
  1517. if exists (select * from sysobjects
  1518.         where name = 'xp_createprivatequeue')
  1519.     execute dbo.sp_dropextendedproc 'xp_createprivatequeue'
  1520.  
  1521. exec sp_addextendedproc 'xp_createprivatequeue', 'xpqueue.dll'
  1522. go
  1523.  
  1524. if exists (select * from sysobjects
  1525.         where name = 'xp_deletequeue')
  1526.     execute dbo.sp_dropextendedproc 'xp_deletequeue'
  1527. go
  1528.  
  1529. if exists (select * from sysobjects
  1530.         where name = 'xp_deleteprivatequeue')
  1531.     execute dbo.sp_dropextendedproc 'xp_deleteprivatequeue'
  1532.  
  1533. exec sp_addextendedproc 'xp_deleteprivatequeue', 'xpqueue.dll'
  1534. go
  1535.  
  1536. if exists (select * from sysobjects
  1537.         where name = 'sp_replsendtoqueue')
  1538.     execute dbo.sp_dropextendedproc 'sp_replsendtoqueue'
  1539. go
  1540.  
  1541. sp_addextendedproc 'sp_replsendtoqueue', 'sp_replsendtoqueue extended proc'
  1542. go
  1543.  
  1544. grant exec on sp_replsendtoqueue to public
  1545. go
  1546.  
  1547. if exists (select * from sysobjects
  1548.         where name = 'sp_replwritetovarbin')
  1549.     execute dbo.sp_dropextendedproc 'sp_replwritetovarbin'
  1550. go
  1551.  
  1552. sp_addextendedproc 'sp_replwritetovarbin', 'sp_replwritetovarbin extended proc'
  1553. go
  1554.  
  1555. grant exec on sp_replwritetovarbin to public
  1556. go
  1557.  
  1558. if exists (select * from sysobjects
  1559.         where name = 'xp_resetqueue')
  1560.     execute dbo.sp_dropextendedproc 'xp_resetqueue'
  1561. go
  1562.  
  1563. sp_addextendedproc 'xp_resetqueue', 'xpqueue.dll'
  1564. go
  1565.  
  1566. if exists (select * from sysobjects
  1567.         where name = 'xp_peekqueue')
  1568.     execute dbo.sp_dropextendedproc 'xp_peekqueue'
  1569. go
  1570.  
  1571. sp_addextendedproc 'xp_peekqueue', 'xpqueue.dll'
  1572. go
  1573.  
  1574. if exists (select * from sysobjects
  1575.         where name = 'xp_controlqueueservice')
  1576.     execute dbo.sp_dropextendedproc 'xp_controlqueueservice'
  1577. go
  1578.  
  1579. sp_addextendedproc 'xp_controlqueueservice', 'xpqueue.dll'
  1580. go
  1581.  
  1582. if exists (select * from sysobjects
  1583.         where name = 'xp_displayqueuemesgs')
  1584.     execute dbo.sp_dropextendedproc 'xp_displayqueuemesgs'
  1585. go
  1586.  
  1587. sp_addextendedproc 'xp_displayqueuemesgs', 'xpqueue.dll'
  1588. go
  1589.  
  1590. if exists (select * from sysobjects
  1591.         where name = 'xp_decodequeuecmd')
  1592.     execute dbo.sp_dropextendedproc 'xp_decodequeuecmd'
  1593. go
  1594.  
  1595. sp_addextendedproc 'xp_decodequeuecmd', 'xpqueue.dll'
  1596. go
  1597.  
  1598. if exists (select * from sysobjects
  1599.         where name = 'xp_readpkfromqueue')
  1600.     execute dbo.sp_dropextendedproc 'xp_readpkfromqueue'
  1601. go
  1602.  
  1603. sp_addextendedproc 'xp_readpkfromqueue', 'xpqueue.dll'
  1604. go
  1605.  
  1606. if exists (select * from sysobjects
  1607.         where name = 'xp_readpkfromvarbin')
  1608.     execute dbo.sp_dropextendedproc 'xp_readpkfromvarbin'
  1609. go
  1610.  
  1611. sp_addextendedproc 'xp_readpkfromvarbin', 'xpqueue.dll'
  1612. go
  1613.  
  1614. /*
  1615. ** Add xp_makecab extended procedure
  1616. */
  1617.  
  1618. if exists (select * from sysobjects
  1619.         where type = 'X'
  1620.             and name = 'xp_makecab')
  1621.     exec dbo.sp_dropextendedproc 'xp_makecab'
  1622. go
  1623.  
  1624. sp_addextendedproc 'xp_makecab', 'xprepl.dll'
  1625. go
  1626. exec dbo.sp_MS_marksystemobject xp_makecab
  1627. go
  1628.  
  1629. /*
  1630. ** Add xp_unpackcab extended procedure
  1631. */
  1632.  
  1633. if exists (select * from sysobjects
  1634.         where type = 'X'
  1635.             and name = 'xp_unpackcab')
  1636.     exec dbo.sp_dropextendedproc 'xp_unpackcab'
  1637. go
  1638.  
  1639. sp_addextendedproc 'xp_unpackcab', 'xprepl.dll'
  1640. go
  1641. exec dbo.sp_MS_marksystemobject xp_unpackcab
  1642. go
  1643.  
  1644. /* Create table dbo.MSreplication_options */
  1645. IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSreplication_options'
  1646.     and type = 'U')
  1647. BEGIN
  1648.     raiserror('Creating procedure Creating table MSreplication_options',0,1)
  1649.     
  1650.  
  1651.     CREATE TABLE dbo.MSreplication_options 
  1652.     (
  1653.     optname            sysname NOT NULL,
  1654.     value            bit NOT NULL,
  1655.     major_version    int NOT NULL,
  1656.     minor_version    int NOT NULL,
  1657.     revision        int NOT NULL,
  1658.     install_failures int NOT NULL
  1659.     )
  1660. END
  1661. GO
  1662.  
  1663. IF NOT EXISTS (SELECT * FROM MSreplication_options WHERE optname = 'transactional')
  1664.     INSERT INTO MSreplication_options VALUES
  1665.         ('transactional',0,0,0,0,0)
  1666. IF NOT EXISTS (SELECT * FROM MSreplication_options WHERE optname = 'merge')
  1667.     INSERT INTO MSreplication_options VALUES
  1668.         ('merge',0,0,0,0,0)
  1669. GO
  1670.  
  1671. -- 
  1672. -- Name:
  1673. --    xp_execresultset
  1674. --
  1675. -- Description: 
  1676. --    This is a wrapper proc to sp_execresultset and provides us
  1677. --  with the ability to change user database context based on
  1678. --  the @dbname provided.
  1679. --
  1680. -- Parameters: 
  1681. --    (see create call below)
  1682. --
  1683. -- Result:
  1684. --
  1685. -- Returns 
  1686. --        0 - succeeded
  1687. --      1 - failed
  1688. --
  1689. -- Security: 
  1690. --    Sysadmin & DBO access only
  1691. --
  1692. raiserror('Creating procedure xp_execresultset', 0,1) with nowait
  1693. go
  1694. create procedure dbo.xp_execresultset
  1695. (
  1696.     @cmd    nvarchar(4000),
  1697.     @dbname    sysname = NULL,
  1698.     @debug    bit = 0
  1699. )
  1700. as
  1701. begin
  1702.     declare @retcode bit,
  1703.             @proc nvarchar(4000)
  1704.     
  1705.     -- check to ensure that the @dbname provided is neither null or empty
  1706.     if isnull(rtrim(@dbname), N'') = N''
  1707.     begin
  1708.         raiserror('Internal Error : @dbname cannot be null or empty.', 16, -1)
  1709.         return 1
  1710.     end
  1711.     
  1712.     select @proc = quotename(@dbname) + N'.dbo.sp_execresultset' 
  1713.  
  1714.     exec @retcode = @proc @cmd, @debug
  1715.     
  1716.     return @retcode
  1717. end
  1718. go
  1719.  
  1720. -- 
  1721. -- Name:
  1722. --    sp_execresultset
  1723. --
  1724. -- Description: 
  1725. --    This procedure replaces the extended stored procedure xp_execresultset.
  1726. --    The proc accepts a query (@cmd) and builds a buffer with the queries
  1727. --    resultset and executes it against the current database. This proc has
  1728. --  a ~1MB limit on the resultset text that can be executed.
  1729. --
  1730. -- Parameters: 
  1731. --    (see create call below)
  1732. --
  1733. -- Result:
  1734. --
  1735. -- Returns 
  1736. --  0 - succeeded
  1737. --  1 - failed
  1738. --
  1739. -- Security: 
  1740. --    Sysadmin & DBO access only
  1741. --
  1742. raiserror('Creating procedure sp_execresultset', 0,1) with nowait
  1743. go
  1744. create procedure dbo.sp_execresultset
  1745. (
  1746.     @cmd     nvarchar(4000),        -- Command that will return a resultset to concat and execute
  1747.     @debug    bit = 0                -- Display debug information and resultset query (no exec)
  1748. )
  1749. as
  1750. begin
  1751.     set nocount on
  1752.  
  1753.     declare @MAXBUFFLEN    int,
  1754.         @qPosition         int,
  1755.         @qValue            nvarchar(4000),
  1756.         @scriptLen         int,
  1757.         @scriptText     nvarchar(4000),
  1758.         @maxIndex        bigint,
  1759.         @rowIndex        bigint
  1760.  
  1761.     -- declare 250 nvarchar(4000) (nearly 1MB worth of space)
  1762.     declare @q1 nvarchar(4000), @q2 nvarchar(4000), @q3 nvarchar(4000), @q4 nvarchar(4000), @q5 nvarchar(4000), @q6 nvarchar(4000), @q7 nvarchar(4000), @q8 nvarchar(4000), @q9 nvarchar(4000), @q10 nvarchar(4000), 
  1763.         @q11 nvarchar(4000), @q12 nvarchar(4000), @q13 nvarchar(4000), @q14 nvarchar(4000), @q15 nvarchar(4000), @q16 nvarchar(4000), @q17 nvarchar(4000), @q18 nvarchar(4000), @q19 nvarchar(4000), @q20 nvarchar(4000), 
  1764.         @q21 nvarchar(4000), @q22 nvarchar(4000), @q23 nvarchar(4000), @q24 nvarchar(4000), @q25 nvarchar(4000), @q26 nvarchar(4000), @q27 nvarchar(4000), @q28 nvarchar(4000), @q29 nvarchar(4000), @q30 nvarchar(4000), 
  1765.         @q31 nvarchar(4000), @q32 nvarchar(4000), @q33 nvarchar(4000), @q34 nvarchar(4000), @q35 nvarchar(4000), @q36 nvarchar(4000), @q37 nvarchar(4000), @q38 nvarchar(4000), @q39 nvarchar(4000), @q40 nvarchar(4000), 
  1766.         @q41 nvarchar(4000), @q42 nvarchar(4000), @q43 nvarchar(4000), @q44 nvarchar(4000), @q45 nvarchar(4000), @q46 nvarchar(4000), @q47 nvarchar(4000), @q48 nvarchar(4000), @q49 nvarchar(4000), @q50 nvarchar(4000), 
  1767.         @q51 nvarchar(4000), @q52 nvarchar(4000), @q53 nvarchar(4000), @q54 nvarchar(4000), @q55 nvarchar(4000), @q56 nvarchar(4000), @q57 nvarchar(4000), @q58 nvarchar(4000), @q59 nvarchar(4000), @q60 nvarchar(4000), 
  1768.         @q61 nvarchar(4000), @q62 nvarchar(4000), @q63 nvarchar(4000), @q64 nvarchar(4000), @q65 nvarchar(4000), @q66 nvarchar(4000), @q67 nvarchar(4000), @q68 nvarchar(4000), @q69 nvarchar(4000), @q70 nvarchar(4000), 
  1769.         @q71 nvarchar(4000), @q72 nvarchar(4000), @q73 nvarchar(4000), @q74 nvarchar(4000), @q75 nvarchar(4000), @q76 nvarchar(4000), @q77 nvarchar(4000), @q78 nvarchar(4000), @q79 nvarchar(4000), @q80 nvarchar(4000), 
  1770.         @q81 nvarchar(4000), @q82 nvarchar(4000), @q83 nvarchar(4000), @q84 nvarchar(4000), @q85 nvarchar(4000), @q86 nvarchar(4000), @q87 nvarchar(4000), @q88 nvarchar(4000), @q89 nvarchar(4000), @q90 nvarchar(4000), 
  1771.         @q91 nvarchar(4000), @q92 nvarchar(4000), @q93 nvarchar(4000), @q94 nvarchar(4000), @q95 nvarchar(4000), @q96 nvarchar(4000), @q97 nvarchar(4000), @q98 nvarchar(4000), @q99 nvarchar(4000), @q100 nvarchar(4000), 
  1772.         @q101 nvarchar(4000), @q102 nvarchar(4000), @q103 nvarchar(4000), @q104 nvarchar(4000), @q105 nvarchar(4000), @q106 nvarchar(4000), @q107 nvarchar(4000), @q108 nvarchar(4000), @q109 nvarchar(4000), @q110 nvarchar(4000), 
  1773.         @q111 nvarchar(4000), @q112 nvarchar(4000), @q113 nvarchar(4000), @q114 nvarchar(4000), @q115 nvarchar(4000), @q116 nvarchar(4000), @q117 nvarchar(4000), @q118 nvarchar(4000), @q119 nvarchar(4000), @q120 nvarchar(4000), 
  1774.         @q121 nvarchar(4000), @q122 nvarchar(4000), @q123 nvarchar(4000), @q124 nvarchar(4000), @q125 nvarchar(4000), @q126 nvarchar(4000), @q127 nvarchar(4000), @q128 nvarchar(4000), @q129 nvarchar(4000), @q130 nvarchar(4000), 
  1775.         @q131 nvarchar(4000), @q132 nvarchar(4000), @q133 nvarchar(4000), @q134 nvarchar(4000), @q135 nvarchar(4000), @q136 nvarchar(4000), @q137 nvarchar(4000), @q138 nvarchar(4000), @q139 nvarchar(4000), @q140 nvarchar(4000), 
  1776.         @q141 nvarchar(4000), @q142 nvarchar(4000), @q143 nvarchar(4000), @q144 nvarchar(4000), @q145 nvarchar(4000), @q146 nvarchar(4000), @q147 nvarchar(4000), @q148 nvarchar(4000), @q149 nvarchar(4000), @q150 nvarchar(4000), 
  1777.         @q151 nvarchar(4000), @q152 nvarchar(4000), @q153 nvarchar(4000), @q154 nvarchar(4000), @q155 nvarchar(4000), @q156 nvarchar(4000), @q157 nvarchar(4000), @q158 nvarchar(4000), @q159 nvarchar(4000), @q160 nvarchar(4000), 
  1778.         @q161 nvarchar(4000), @q162 nvarchar(4000), @q163 nvarchar(4000), @q164 nvarchar(4000), @q165 nvarchar(4000), @q166 nvarchar(4000), @q167 nvarchar(4000), @q168 nvarchar(4000), @q169 nvarchar(4000), @q170 nvarchar(4000), 
  1779.         @q171 nvarchar(4000), @q172 nvarchar(4000), @q173 nvarchar(4000), @q174 nvarchar(4000), @q175 nvarchar(4000), @q176 nvarchar(4000), @q177 nvarchar(4000), @q178 nvarchar(4000), @q179 nvarchar(4000), @q180 nvarchar(4000), 
  1780.         @q181 nvarchar(4000), @q182 nvarchar(4000), @q183 nvarchar(4000), @q184 nvarchar(4000), @q185 nvarchar(4000), @q186 nvarchar(4000), @q187 nvarchar(4000), @q188 nvarchar(4000), @q189 nvarchar(4000), @q190 nvarchar(4000), 
  1781.         @q191 nvarchar(4000), @q192 nvarchar(4000), @q193 nvarchar(4000), @q194 nvarchar(4000), @q195 nvarchar(4000), @q196 nvarchar(4000), @q197 nvarchar(4000), @q198 nvarchar(4000), @q199 nvarchar(4000), @q200 nvarchar(4000), 
  1782.         @q201 nvarchar(4000), @q202 nvarchar(4000), @q203 nvarchar(4000), @q204 nvarchar(4000), @q205 nvarchar(4000), @q206 nvarchar(4000), @q207 nvarchar(4000), @q208 nvarchar(4000), @q209 nvarchar(4000), @q210 nvarchar(4000), 
  1783.         @q211 nvarchar(4000), @q212 nvarchar(4000), @q213 nvarchar(4000), @q214 nvarchar(4000), @q215 nvarchar(4000), @q216 nvarchar(4000), @q217 nvarchar(4000), @q218 nvarchar(4000), @q219 nvarchar(4000), @q220 nvarchar(4000), 
  1784.         @q221 nvarchar(4000), @q222 nvarchar(4000), @q223 nvarchar(4000), @q224 nvarchar(4000), @q225 nvarchar(4000), @q226 nvarchar(4000), @q227 nvarchar(4000), @q228 nvarchar(4000), @q229 nvarchar(4000), @q230 nvarchar(4000), 
  1785.         @q231 nvarchar(4000), @q232 nvarchar(4000), @q233 nvarchar(4000), @q234 nvarchar(4000), @q235 nvarchar(4000), @q236 nvarchar(4000), @q237 nvarchar(4000), @q238 nvarchar(4000), @q239 nvarchar(4000), @q240 nvarchar(4000), 
  1786.         @q241 nvarchar(4000), @q242 nvarchar(4000), @q243 nvarchar(4000), @q244 nvarchar(4000), @q245 nvarchar(4000), @q246 nvarchar(4000), @q247 nvarchar(4000), @q248 nvarchar(4000), @q249 nvarchar(4000), @q250 nvarchar(4000) 
  1787.  
  1788.     -- initialize all vars
  1789.     select @q1 = N'', @q2 = N'', @q3 = N'', @q4 = N'', @q5 = N'', @q6 = N'', @q7 = N'', @q8 = N'', @q9 = N'', @q10 = N'', 
  1790.         @q11 = N'', @q12 = N'', @q13 = N'', @q14 = N'', @q15 = N'', @q16 = N'', @q17 = N'', @q18 = N'', @q19 = N'', @q20 = N'', 
  1791.         @q21 = N'', @q22 = N'', @q23 = N'', @q24 = N'', @q25 = N'', @q26 = N'', @q27 = N'', @q28 = N'', @q29 = N'', @q30 = N'', 
  1792.         @q31 = N'', @q32 = N'', @q33 = N'', @q34 = N'', @q35 = N'', @q36 = N'', @q37 = N'', @q38 = N'', @q39 = N'', @q40 = N'', 
  1793.         @q41 = N'', @q42 = N'', @q43 = N'', @q44 = N'', @q45 = N'', @q46 = N'', @q47 = N'', @q48 = N'', @q49 = N'', @q50 = N'', 
  1794.         @q51 = N'', @q52 = N'', @q53 = N'', @q54 = N'', @q55 = N'', @q56 = N'', @q57 = N'', @q58 = N'', @q59 = N'', @q60 = N'', 
  1795.         @q61 = N'', @q62 = N'', @q63 = N'', @q64 = N'', @q65 = N'', @q66 = N'', @q67 = N'', @q68 = N'', @q69 = N'', @q70 = N'', 
  1796.         @q71 = N'', @q72 = N'', @q73 = N'', @q74 = N'', @q75 = N'', @q76 = N'', @q77 = N'', @q78 = N'', @q79 = N'', @q80 = N'', 
  1797.         @q81 = N'', @q82 = N'', @q83 = N'', @q84 = N'', @q85 = N'', @q86 = N'', @q87 = N'', @q88 = N'', @q89 = N'', @q90 = N'', 
  1798.         @q91 = N'', @q92 = N'', @q93 = N'', @q94 = N'', @q95 = N'', @q96 = N'', @q97 = N'', @q98 = N'', @q99 = N'', @q100 = N'', 
  1799.         @q101 = N'', @q102 = N'', @q103 = N'', @q104 = N'', @q105 = N'', @q106 = N'', @q107 = N'', @q108 = N'', @q109 = N'', @q110 = N'', 
  1800.         @q111 = N'', @q112 = N'', @q113 = N'', @q114 = N'', @q115 = N'', @q116 = N'', @q117 = N'', @q118 = N'', @q119 = N'', @q120 = N'', 
  1801.         @q121 = N'', @q122 = N'', @q123 = N'', @q124 = N'', @q125 = N'', @q126 = N'', @q127 = N'', @q128 = N'', @q129 = N'', @q130 = N'', 
  1802.         @q131 = N'', @q132 = N'', @q133 = N'', @q134 = N'', @q135 = N'', @q136 = N'', @q137 = N'', @q138 = N'', @q139 = N'', @q140 = N'', 
  1803.         @q141 = N'', @q142 = N'', @q143 = N'', @q144 = N'', @q145 = N'', @q146 = N'', @q147 = N'', @q148 = N'', @q149 = N'', @q150 = N'', 
  1804.         @q151 = N'', @q152 = N'', @q153 = N'', @q154 = N'', @q155 = N'', @q156 = N'', @q157 = N'', @q158 = N'', @q159 = N'', @q160 = N'', 
  1805.         @q161 = N'', @q162 = N'', @q163 = N'', @q164 = N'', @q165 = N'', @q166 = N'', @q167 = N'', @q168 = N'', @q169 = N'', @q170 = N'', 
  1806.         @q171 = N'', @q172 = N'', @q173 = N'', @q174 = N'', @q175 = N'', @q176 = N'', @q177 = N'', @q178 = N'', @q179 = N'', @q180 = N'', 
  1807.         @q181 = N'', @q182 = N'', @q183 = N'', @q184 = N'', @q185 = N'', @q186 = N'', @q187 = N'', @q188 = N'', @q189 = N'', @q190 = N'', 
  1808.         @q191 = N'', @q192 = N'', @q193 = N'', @q194 = N'', @q195 = N'', @q196 = N'', @q197 = N'', @q198 = N'', @q199 = N'', @q200 = N'', 
  1809.         @q201 = N'', @q202 = N'', @q203 = N'', @q204 = N'', @q205 = N'', @q206 = N'', @q207 = N'', @q208 = N'', @q209 = N'', @q210 = N'', 
  1810.         @q211 = N'', @q212 = N'', @q213 = N'', @q214 = N'', @q215 = N'', @q216 = N'', @q217 = N'', @q218 = N'', @q219 = N'', @q220 = N'', 
  1811.         @q221 = N'', @q222 = N'', @q223 = N'', @q224 = N'', @q225 = N'', @q226 = N'', @q227 = N'', @q228 = N'', @q229 = N'', @q230 = N'', 
  1812.         @q231 = N'', @q232 = N'', @q233 = N'', @q234 = N'', @q235 = N'', @q236 = N'', @q237 = N'', @q238 = N'', @q239 = N'', @q240 = N'', 
  1813.         @q241 = N'', @q242 = N'', @q243 = N'', @q244 = N'', @q245 = N'', @q246 = N'', @q247 = N'', @q248 = N'', @q249 = N'', @q250 = N''
  1814.  
  1815.     select @MAXBUFFLEN     = 4000,
  1816.         @qPosition        = 1,
  1817.         @qValue            = N'',
  1818.         @scriptLen        = 0,
  1819.         @scriptText     = N''
  1820.  
  1821.     -- check if our scripting table exists, if so let's drop it    
  1822.     if object_id('tempdb..#MSrepl_exec_script', 'U') is not null
  1823.     begin
  1824.         drop table #MSrepl_exec_script
  1825.     end
  1826.  
  1827.     -- create and load a local tmp table with the resultset based off of the cmd provided
  1828.     create table #MSrepl_exec_script (orderCol int identity(1,1) primary key clustered, scriptText nvarchar(4000))
  1829.     if @@error <> 0
  1830.     begin
  1831.         goto Error
  1832.     end
  1833.  
  1834.     insert into #MSrepl_exec_script(scriptText) exec(@cmd)
  1835.     if @@error <> 0
  1836.     begin
  1837.         goto Error
  1838.     end
  1839.     
  1840.     -- get the max value inserted in the identity col for 
  1841.     -- #MSrepl_exec_script table and set the rowIndex = 1
  1842.     select @maxIndex = max(orderCol),
  1843.             @rowIndex = 1
  1844.         from #MSrepl_exec_script
  1845.  
  1846.     -- retrieve the current scriptText row 
  1847.     select @scriptText = isnull(scriptText, N'')
  1848.         from #MSrepl_exec_script
  1849.         where orderCol = @rowIndex
  1850.  
  1851.     while (@rowIndex <= @maxIndex)
  1852.     begin
  1853.         select @scriptLen = @scriptLen + datalength(@scriptText)/2
  1854.         if (@scriptLen < @MAXBUFFLEN)
  1855.         begin
  1856.             -- for this case we continue to append since we know we have room
  1857.             select @qValue = @qValue + @scriptText + N' '
  1858.             
  1859.             -- add one to the script length for the space we just added
  1860.             select @scriptLen = @scriptLen + 1
  1861.  
  1862.             -- increment the row position counter
  1863.             select @rowIndex = @rowIndex + 1
  1864.  
  1865.             -- retrieve the current scriptText row
  1866.             select @scriptText = isnull(scriptText, N'')
  1867.                 from #MSrepl_exec_script
  1868.                 where orderCol = @rowIndex
  1869.  
  1870.             -- If there are no more script pieces then we will not continue
  1871.             -- instead we will set the current @qPosition and the loop will exit
  1872.             --
  1873.             -- Also be sure that if we reach the MAXBUFFLEN at this point we do not 
  1874.             -- continue. Instead we want to set the value below first before we continue.
  1875.             -- FYI: It will never be possible to be greater than MAXBUFFLEN in this section.
  1876.             if(@rowIndex <= @maxIndex and @scriptLen != @MAXBUFFLEN)
  1877.             begin
  1878.                 continue
  1879.             end
  1880.         end
  1881.         else if (@scriptLen > @MAXBUFFLEN)
  1882.         begin
  1883.             -- here we have exceeded the @MAXBUFFLEN char limit so we will 
  1884.             -- fill the @qValue buffer and then store off the remaining  
  1885.             -- scriptText to be appended on the next itteration of the loop
  1886.  
  1887.             select @qValue = @qValue + left(@scriptText, @MAXBUFFLEN - datalength(@qValue)/2)
  1888.  
  1889.             select @scriptText = right(@scriptText, @scriptLen - @MAXBUFFLEN)    
  1890.         end
  1891.         else
  1892.         begin
  1893.             -- Append the entire scriptText since we know we have room. Do not 
  1894.             -- add the command seperator (space) since there is no room for that
  1895.             select @qValue = @qValue + @scriptText
  1896.  
  1897.             -- set the scripttext to empty so that on the next loop 
  1898.             -- we will add a space to the first qPostition buffer 
  1899.             select @scriptText = N''
  1900.         end
  1901.  
  1902.         -- set one of the 250 vars
  1903.         -- we need to break this 'else if' list by 100 because there is a limit of nesting levels
  1904.         -- this is a good idea in any case because it should speed things up a bit
  1905.         if @qPosition <= 100
  1906.         begin
  1907.             if @qPosition = 1 select @q1 = @qValue else if @qPosition = 2 select @q2 = @qValue else if @qPosition = 3 select @q3 = @qValue else if @qPosition = 4 select @q4 = @qValue else if @qPosition = 5 select @q5 = @qValue else if @qPosition = 6 select @q6 = @qValue else if @qPosition = 7 select @q7 = @qValue else if @qPosition = 8 select @q8 = @qValue else if @qPosition = 9 select @q9 = @qValue else if @qPosition = 10 select @q10 = @qValue 
  1908.             else if @qPosition = 11 select @q11 = @qValue else if @qPosition = 12 select @q12 = @qValue else if @qPosition = 13 select @q13 = @qValue else if @qPosition = 14 select @q14 = @qValue else if @qPosition = 15 select @q15 = @qValue else if @qPosition = 16 select @q16 = @qValue else if @qPosition = 17 select @q17 = @qValue else if @qPosition = 18 select @q18 = @qValue else if @qPosition = 19 select @q19 = @qValue else if @qPosition = 20 select @q20 = @qValue 
  1909.             else if @qPosition = 21 select @q21 = @qValue else if @qPosition = 22 select @q22 = @qValue else if @qPosition = 23 select @q23 = @qValue else if @qPosition = 24 select @q24 = @qValue else if @qPosition = 25 select @q25 = @qValue else if @qPosition = 26 select @q26 = @qValue else if @qPosition = 27 select @q27 = @qValue else if @qPosition = 28 select @q28 = @qValue else if @qPosition = 29 select @q29 = @qValue else if @qPosition = 30 select @q30 = @qValue 
  1910.             else if @qPosition = 31 select @q31 = @qValue else if @qPosition = 32 select @q32 = @qValue else if @qPosition = 33 select @q33 = @qValue else if @qPosition = 34 select @q34 = @qValue else if @qPosition = 35 select @q35 = @qValue else if @qPosition = 36 select @q36 = @qValue else if @qPosition = 37 select @q37 = @qValue else if @qPosition = 38 select @q38 = @qValue else if @qPosition = 39 select @q39 = @qValue else if @qPosition = 40 select @q40 = @qValue 
  1911.             else if @qPosition = 41 select @q41 = @qValue else if @qPosition = 42 select @q42 = @qValue else if @qPosition = 43 select @q43 = @qValue else if @qPosition = 44 select @q44 = @qValue else if @qPosition = 45 select @q45 = @qValue else if @qPosition = 46 select @q46 = @qValue else if @qPosition = 47 select @q47 = @qValue else if @qPosition = 48 select @q48 = @qValue else if @qPosition = 49 select @q49 = @qValue else if @qPosition = 50 select @q50 = @qValue 
  1912.             else if @qPosition = 51 select @q51 = @qValue else if @qPosition = 52 select @q52 = @qValue else if @qPosition = 53 select @q53 = @qValue else if @qPosition = 54 select @q54 = @qValue else if @qPosition = 55 select @q55 = @qValue else if @qPosition = 56 select @q56 = @qValue else if @qPosition = 57 select @q57 = @qValue else if @qPosition = 58 select @q58 = @qValue else if @qPosition = 59 select @q59 = @qValue else if @qPosition = 60 select @q60 = @qValue 
  1913.             else if @qPosition = 61 select @q61 = @qValue else if @qPosition = 62 select @q62 = @qValue else if @qPosition = 63 select @q63 = @qValue else if @qPosition = 64 select @q64 = @qValue else if @qPosition = 65 select @q65 = @qValue else if @qPosition = 66 select @q66 = @qValue else if @qPosition = 67 select @q67 = @qValue else if @qPosition = 68 select @q68 = @qValue else if @qPosition = 69 select @q69 = @qValue else if @qPosition = 70 select @q70 = @qValue 
  1914.             else if @qPosition = 71 select @q71 = @qValue else if @qPosition = 72 select @q72 = @qValue else if @qPosition = 73 select @q73 = @qValue else if @qPosition = 74 select @q74 = @qValue else if @qPosition = 75 select @q75 = @qValue else if @qPosition = 76 select @q76 = @qValue else if @qPosition = 77 select @q77 = @qValue else if @qPosition = 78 select @q78 = @qValue else if @qPosition = 79 select @q79 = @qValue else if @qPosition = 80 select @q80 = @qValue 
  1915.             else if @qPosition = 81 select @q81 = @qValue else if @qPosition = 82 select @q82 = @qValue else if @qPosition = 83 select @q83 = @qValue else if @qPosition = 84 select @q84 = @qValue else if @qPosition = 85 select @q85 = @qValue else if @qPosition = 86 select @q86 = @qValue else if @qPosition = 87 select @q87 = @qValue else if @qPosition = 88 select @q88 = @qValue else if @qPosition = 89 select @q89 = @qValue else if @qPosition = 90 select @q90 = @qValue 
  1916.             else if @qPosition = 91 select @q91 = @qValue else if @qPosition = 92 select @q92 = @qValue else if @qPosition = 93 select @q93 = @qValue else if @qPosition = 94 select @q94 = @qValue else if @qPosition = 95 select @q95 = @qValue else if @qPosition = 96 select @q96 = @qValue else if @qPosition = 97 select @q97 = @qValue else if @qPosition = 98 select @q98 = @qValue else if @qPosition = 99 select @q99 = @qValue else if @qPosition = 100 select @q100 = @qValue
  1917.         end
  1918.         else if @qPosition <= 200   
  1919.         begin
  1920.             if @qPosition = 101 select @q101 = @qValue else if @qPosition = 102 select @q102 = @qValue else if @qPosition = 103 select @q103 = @qValue else if @qPosition = 104 select @q104 = @qValue else if @qPosition = 105 select @q105 = @qValue else if @qPosition = 106 select @q106 = @qValue else if @qPosition = 107 select @q107 = @qValue else if @qPosition = 108 select @q108 = @qValue else if @qPosition = 109 select @q109 = @qValue else if @qPosition = 110 select @q110 = @qValue
  1921.             else if @qPosition = 111 select @q111 = @qValue else if @qPosition = 112 select @q112 = @qValue else if @qPosition = 113 select @q113 = @qValue else if @qPosition = 114 select @q114 = @qValue else if @qPosition = 115 select @q115 = @qValue else if @qPosition = 116 select @q116 = @qValue else if @qPosition = 117 select @q117 = @qValue else if @qPosition = 118 select @q118 = @qValue else if @qPosition = 119 select @q119 = @qValue else if @qPosition = 120 select @q120 = @qValue
  1922.             else if @qPosition = 121 select @q121 = @qValue else if @qPosition = 122 select @q122 = @qValue else if @qPosition = 123 select @q123 = @qValue else if @qPosition = 124 select @q124 = @qValue else if @qPosition = 125 select @q125 = @qValue else if @qPosition = 126 select @q126 = @qValue else if @qPosition = 127 select @q127 = @qValue else if @qPosition = 128 select @q128 = @qValue else if @qPosition = 129 select @q129 = @qValue else if @qPosition = 130 select @q130 = @qValue 
  1923.             else if @qPosition = 131 select @q131 = @qValue else if @qPosition = 132 select @q132 = @qValue else if @qPosition = 133 select @q133 = @qValue else if @qPosition = 134 select @q134 = @qValue else if @qPosition = 135 select @q135 = @qValue else if @qPosition = 136 select @q136 = @qValue else if @qPosition = 137 select @q137 = @qValue else if @qPosition = 138 select @q138 = @qValue else if @qPosition = 139 select @q139 = @qValue else if @qPosition = 140 select @q140 = @qValue 
  1924.             else if @qPosition = 141 select @q141 = @qValue else if @qPosition = 142 select @q142 = @qValue else if @qPosition = 143 select @q143 = @qValue else if @qPosition = 144 select @q144 = @qValue else if @qPosition = 145 select @q145 = @qValue else if @qPosition = 146 select @q146 = @qValue else if @qPosition = 147 select @q147 = @qValue else if @qPosition = 148 select @q148 = @qValue else if @qPosition = 149 select @q149 = @qValue else if @qPosition = 150 select @q150 = @qValue 
  1925.             else if @qPosition = 151 select @q151 = @qValue else if @qPosition = 152 select @q152 = @qValue else if @qPosition = 153 select @q153 = @qValue else if @qPosition = 154 select @q154 = @qValue else if @qPosition = 155 select @q155 = @qValue else if @qPosition = 156 select @q156 = @qValue else if @qPosition = 157 select @q157 = @qValue else if @qPosition = 158 select @q158 = @qValue else if @qPosition = 159 select @q159 = @qValue else if @qPosition = 160 select @q160 = @qValue 
  1926.             else if @qPosition = 161 select @q161 = @qValue else if @qPosition = 162 select @q162 = @qValue else if @qPosition = 163 select @q163 = @qValue else if @qPosition = 164 select @q164 = @qValue else if @qPosition = 165 select @q165 = @qValue else if @qPosition = 166 select @q166 = @qValue else if @qPosition = 167 select @q167 = @qValue else if @qPosition = 168 select @q168 = @qValue else if @qPosition = 169 select @q169 = @qValue else if @qPosition = 170 select @q170 = @qValue 
  1927.             else if @qPosition = 171 select @q171 = @qValue else if @qPosition = 172 select @q172 = @qValue else if @qPosition = 173 select @q173 = @qValue else if @qPosition = 174 select @q174 = @qValue else if @qPosition = 175 select @q175 = @qValue else if @qPosition = 176 select @q176 = @qValue else if @qPosition = 177 select @q177 = @qValue else if @qPosition = 178 select @q178 = @qValue else if @qPosition = 179 select @q179 = @qValue else if @qPosition = 180 select @q180 = @qValue 
  1928.             else if @qPosition = 181 select @q181 = @qValue else if @qPosition = 182 select @q182 = @qValue else if @qPosition = 183 select @q183 = @qValue else if @qPosition = 184 select @q184 = @qValue else if @qPosition = 185 select @q185 = @qValue else if @qPosition = 186 select @q186 = @qValue else if @qPosition = 187 select @q187 = @qValue else if @qPosition = 188 select @q188 = @qValue else if @qPosition = 189 select @q189 = @qValue else if @qPosition = 190 select @q190 = @qValue 
  1929.             else if @qPosition = 191 select @q191 = @qValue else if @qPosition = 192 select @q192 = @qValue else if @qPosition = 193 select @q193 = @qValue else if @qPosition = 194 select @q194 = @qValue else if @qPosition = 195 select @q195 = @qValue else if @qPosition = 196 select @q196 = @qValue else if @qPosition = 197 select @q197 = @qValue else if @qPosition = 198 select @q198 = @qValue else if @qPosition = 199 select @q199 = @qValue else if @qPosition = 200 select @q200 = @qValue
  1930.         end
  1931.         else
  1932.         begin
  1933.             if @qPosition = 201 select @q201 = @qValue else if @qPosition = 202 select @q202 = @qValue else if @qPosition = 203 select @q203 = @qValue else if @qPosition = 204 select @q204 = @qValue else if @qPosition = 205 select @q205 = @qValue else if @qPosition = 206 select @q206 = @qValue else if @qPosition = 207 select @q207 = @qValue else if @qPosition = 208 select @q208 = @qValue else if @qPosition = 209 select @q209 = @qValue else if @qPosition = 210 select @q210 = @qValue 
  1934.             else if @qPosition = 211 select @q211 = @qValue else if @qPosition = 212 select @q212 = @qValue else if @qPosition = 213 select @q213 = @qValue else if @qPosition = 214 select @q214 = @qValue else if @qPosition = 215 select @q215 = @qValue else if @qPosition = 216 select @q216 = @qValue else if @qPosition = 217 select @q217 = @qValue else if @qPosition = 218 select @q218 = @qValue else if @qPosition = 219 select @q219 = @qValue else if @qPosition = 220 select @q220 = @qValue 
  1935.             else if @qPosition = 221 select @q221 = @qValue else if @qPosition = 222 select @q222 = @qValue else if @qPosition = 223 select @q223 = @qValue else if @qPosition = 224 select @q224 = @qValue else if @qPosition = 225 select @q225 = @qValue else if @qPosition = 226 select @q226 = @qValue else if @qPosition = 227 select @q227 = @qValue else if @qPosition = 228 select @q228 = @qValue else if @qPosition = 229 select @q229 = @qValue else if @qPosition = 230 select @q230 = @qValue 
  1936.             else if @qPosition = 231 select @q231 = @qValue else if @qPosition = 232 select @q232 = @qValue else if @qPosition = 233 select @q233 = @qValue else if @qPosition = 234 select @q234 = @qValue else if @qPosition = 235 select @q235 = @qValue else if @qPosition = 236 select @q236 = @qValue else if @qPosition = 237 select @q237 = @qValue else if @qPosition = 238 select @q238 = @qValue else if @qPosition = 239 select @q239 = @qValue else if @qPosition = 240 select @q240 = @qValue 
  1937.             else if @qPosition = 241 select @q241 = @qValue else if @qPosition = 242 select @q242 = @qValue else if @qPosition = 243 select @q243 = @qValue else if @qPosition = 244 select @q244 = @qValue else if @qPosition = 245 select @q245 = @qValue else if @qPosition = 246 select @q246 = @qValue else if @qPosition = 247 select @q247 = @qValue else if @qPosition = 248 select @q248 = @qValue else if @qPosition = 249 select @q249 = @qValue else if @qPosition = 250 select @q250 = @qValue
  1938.             
  1939.             if @qPosition > 250
  1940.             begin
  1941.                 raiserror('Internal Error : Command buffer limit of ~1MB has been reached! Resultset will not be executed.', 16, -1)
  1942.                 goto Error
  1943.             end
  1944.         end
  1945.  
  1946.         -- Since we just filled a buffer move the index value by one
  1947.         -- and reset the current query row value to empty and len to 0
  1948.         select @qPosition    = @qPosition + 1,
  1949.             @qValue        = N'',
  1950.             @scriptLen    = 0
  1951.     end
  1952.     
  1953.     if @debug = 0
  1954.     begin
  1955.         -- concat all buffers and execute
  1956.         exec(@q1+@q2+@q3+@q4+@q5+@q6+@q7+@q8+@q9+@q10+
  1957.             @q11+@q12+@q13+@q14+@q15+@q16+@q17+@q18+@q19+@q20+
  1958.             @q21+@q22+@q23+@q24+@q25+@q26+@q27+@q28+@q29+@q30+
  1959.             @q31+@q32+@q33+@q34+@q35+@q36+@q37+@q38+@q39+@q40+
  1960.             @q41+@q42+@q43+@q44+@q45+@q46+@q47+@q48+@q49+@q50+
  1961.             @q51+@q52+@q53+@q54+@q55+@q56+@q57+@q58+@q59+@q60+
  1962.             @q61+@q62+@q63+@q64+@q65+@q66+@q67+@q68+@q69+@q70+
  1963.             @q71+@q72+@q73+@q74+@q75+@q76+@q77+@q78+@q79+@q80+
  1964.             @q81+@q82+@q83+@q84+@q85+@q86+@q87+@q88+@q89+@q90+
  1965.             @q91+@q92+@q93+@q94+@q95+@q96+@q97+@q98+@q99+@q100+
  1966.             @q101+@q102+@q103+@q104+@q105+@q106+@q107+@q108+@q109+@q110+
  1967.             @q111+@q112+@q113+@q114+@q115+@q116+@q117+@q118+@q119+@q120+
  1968.             @q121+@q122+@q123+@q124+@q125+@q126+@q127+@q128+@q129+@q130+
  1969.             @q131+@q132+@q133+@q134+@q135+@q136+@q137+@q138+@q139+@q140+
  1970.             @q141+@q142+@q143+@q144+@q145+@q146+@q147+@q148+@q149+@q150+
  1971.             @q151+@q152+@q153+@q154+@q155+@q156+@q157+@q158+@q159+@q160+
  1972.             @q161+@q162+@q163+@q164+@q165+@q166+@q167+@q168+@q169+@q170+
  1973.             @q171+@q172+@q173+@q174+@q175+@q176+@q177+@q178+@q179+@q180+
  1974.             @q181+@q182+@q183+@q184+@q185+@q186+@q187+@q188+@q189+@q190+
  1975.             @q191+@q192+@q193+@q194+@q195+@q196+@q197+@q198+@q199+@q200+
  1976.             @q201+@q202+@q203+@q204+@q205+@q206+@q207+@q208+@q209+@q210+
  1977.             @q211+@q212+@q213+@q214+@q215+@q216+@q217+@q218+@q219+@q220+
  1978.             @q221+@q222+@q223+@q224+@q225+@q226+@q227+@q228+@q229+@q230+
  1979.             @q231+@q232+@q233+@q234+@q235+@q236+@q237+@q238+@q239+@q240+
  1980.             @q241+@q242+@q243+@q244+@q245+@q246+@q247+@q248+@q249+@q250)
  1981.         if @@error <> 0
  1982.         begin
  1983.             goto Error
  1984.         end
  1985.     end
  1986.     else
  1987.     begin
  1988.         -- print out debug info
  1989.         select '@q1' = datalength(@q1)/2, '@q2' = datalength(@q2)/2, '@q3' = datalength(@q3)/2, '@q4' = datalength(@q4)/2, '@q5' = datalength(@q5)/2, '@q6' = datalength(@q6)/2, '@q7' = datalength(@q7)/2, '@q8' = datalength(@q8)/2, '@q9' = datalength(@q9)/2, '@q10' = datalength(@q10)/2, 
  1990.             '@q11' = datalength(@q11)/2, '@q12' = datalength(@q12)/2, '@q13' = datalength(@q13)/2, '@q14' = datalength(@q14)/2, '@q15' = datalength(@q15)/2, '@q16' = datalength(@q16)/2, '@q17' = datalength(@q17)/2, '@q18' = datalength(@q18)/2, '@q19' = datalength(@q19)/2, '@q20' = datalength(@q20)/2, 
  1991.             '@q21' = datalength(@q21)/2, '@q22' = datalength(@q22)/2, '@q23' = datalength(@q23)/2, '@q24' = datalength(@q24)/2, '@q25' = datalength(@q25)/2, '@q26' = datalength(@q26)/2, '@q27' = datalength(@q27)/2, '@q28' = datalength(@q28)/2, '@q29' = datalength(@q29)/2, '@q30' = datalength(@q30)/2, 
  1992.             '@q31' = datalength(@q31)/2, '@q32' = datalength(@q32)/2, '@q33' = datalength(@q33)/2, '@q34' = datalength(@q34)/2, '@q35' = datalength(@q35)/2, '@q36' = datalength(@q36)/2, '@q37' = datalength(@q37)/2, '@q38' = datalength(@q38)/2, '@q39' = datalength(@q39)/2, '@q40' = datalength(@q40)/2, 
  1993.             '@q41' = datalength(@q41)/2, '@q42' = datalength(@q42)/2, '@q43' = datalength(@q43)/2, '@q44' = datalength(@q44)/2, '@q45' = datalength(@q45)/2, '@q46' = datalength(@q46)/2, '@q47' = datalength(@q47)/2, '@q48' = datalength(@q48)/2, '@q49' = datalength(@q49)/2, '@q50' = datalength(@q50)/2, 
  1994.             '@q51' = datalength(@q51)/2, '@q52' = datalength(@q52)/2, '@q53' = datalength(@q53)/2, '@q54' = datalength(@q54)/2, '@q55' = datalength(@q55)/2, '@q56' = datalength(@q56)/2, '@q57' = datalength(@q57)/2, '@q58' = datalength(@q58)/2, '@q59' = datalength(@q59)/2, '@q60' = datalength(@q60)/2, 
  1995.             '@q61' = datalength(@q61)/2, '@q62' = datalength(@q62)/2, '@q63' = datalength(@q63)/2, '@q64' = datalength(@q64)/2, '@q65' = datalength(@q65)/2, '@q66' = datalength(@q66)/2, '@q67' = datalength(@q67)/2, '@q68' = datalength(@q68)/2, '@q69' = datalength(@q69)/2, '@q70' = datalength(@q70)/2, 
  1996.             '@q71' = datalength(@q71)/2, '@q72' = datalength(@q72)/2, '@q73' = datalength(@q73)/2, '@q74' = datalength(@q74)/2, '@q75' = datalength(@q75)/2, '@q76' = datalength(@q76)/2, '@q77' = datalength(@q77)/2, '@q78' = datalength(@q78)/2, '@q79' = datalength(@q79)/2, '@q80' = datalength(@q80)/2, 
  1997.             '@q81' = datalength(@q81)/2, '@q82' = datalength(@q82)/2, '@q83' = datalength(@q83)/2, '@q84' = datalength(@q84)/2, '@q85' = datalength(@q85)/2, '@q86' = datalength(@q86)/2, '@q87' = datalength(@q87)/2, '@q88' = datalength(@q88)/2, '@q89' = datalength(@q89)/2, '@q90' = datalength(@q90)/2, 
  1998.             '@q91' = datalength(@q91)/2, '@q92' = datalength(@q92)/2, '@q93' = datalength(@q93)/2, '@q94' = datalength(@q94)/2, '@q95' = datalength(@q95)/2, '@q96' = datalength(@q96)/2, '@q97' = datalength(@q97)/2, '@q98' = datalength(@q98)/2, '@q99' = datalength(@q99)/2, '@q100' = datalength(@q100)/2, 
  1999.             '@q101' = datalength(@q101)/2, '@q102' = datalength(@q102)/2, '@q103' = datalength(@q103)/2, '@q104' = datalength(@q104)/2, '@q105' = datalength(@q105)/2, '@q106' = datalength(@q106)/2, '@q107' = datalength(@q107)/2, '@q108' = datalength(@q108)/2, '@q109' = datalength(@q109)/2, '@q110' = datalength(@q110)/2, 
  2000.             '@q111' = datalength(@q111)/2, '@q112' = datalength(@q112)/2, '@q113' = datalength(@q113)/2, '@q114' = datalength(@q114)/2, '@q115' = datalength(@q115)/2, '@q116' = datalength(@q116)/2, '@q117' = datalength(@q117)/2, '@q118' = datalength(@q118)/2, '@q119' = datalength(@q119)/2, '@q120' = datalength(@q120)/2, 
  2001.             '@q121' = datalength(@q121)/2, '@q122' = datalength(@q122)/2, '@q123' = datalength(@q123)/2, '@q124' = datalength(@q124)/2, '@q125' = datalength(@q125)/2, '@q126' = datalength(@q126)/2, '@q127' = datalength(@q127)/2, '@q128' = datalength(@q128)/2, '@q129' = datalength(@q129)/2, '@q130' = datalength(@q130)/2, 
  2002.             '@q131' = datalength(@q131)/2, '@q132' = datalength(@q132)/2, '@q133' = datalength(@q133)/2, '@q134' = datalength(@q134)/2, '@q135' = datalength(@q135)/2, '@q136' = datalength(@q136)/2, '@q137' = datalength(@q137)/2, '@q138' = datalength(@q138)/2, '@q139' = datalength(@q139)/2, '@q140' = datalength(@q140)/2, 
  2003.             '@q141' = datalength(@q141)/2, '@q142' = datalength(@q142)/2, '@q143' = datalength(@q143)/2, '@q144' = datalength(@q144)/2, '@q145' = datalength(@q145)/2, '@q146' = datalength(@q146)/2, '@q147' = datalength(@q147)/2, '@q148' = datalength(@q148)/2, '@q149' = datalength(@q149)/2, '@q150' = datalength(@q150)/2, 
  2004.             '@q151' = datalength(@q151)/2, '@q152' = datalength(@q152)/2, '@q153' = datalength(@q153)/2, '@q154' = datalength(@q154)/2, '@q155' = datalength(@q155)/2, '@q156' = datalength(@q156)/2, '@q157' = datalength(@q157)/2, '@q158' = datalength(@q158)/2, '@q159' = datalength(@q159)/2, '@q160' = datalength(@q160)/2, 
  2005.             '@q161' = datalength(@q161)/2, '@q162' = datalength(@q162)/2, '@q163' = datalength(@q163)/2, '@q164' = datalength(@q164)/2, '@q165' = datalength(@q165)/2, '@q166' = datalength(@q166)/2, '@q167' = datalength(@q167)/2, '@q168' = datalength(@q168)/2, '@q169' = datalength(@q169)/2, '@q170' = datalength(@q170)/2, 
  2006.             '@q171' = datalength(@q171)/2, '@q172' = datalength(@q172)/2, '@q173' = datalength(@q173)/2, '@q174' = datalength(@q174)/2, '@q175' = datalength(@q175)/2, '@q176' = datalength(@q176)/2, '@q177' = datalength(@q177)/2, '@q178' = datalength(@q178)/2, '@q179' = datalength(@q179)/2, '@q180' = datalength(@q180)/2, 
  2007.             '@q181' = datalength(@q181)/2, '@q182' = datalength(@q182)/2, '@q183' = datalength(@q183)/2, '@q184' = datalength(@q184)/2, '@q185' = datalength(@q185)/2, '@q186' = datalength(@q186)/2, '@q187' = datalength(@q187)/2, '@q188' = datalength(@q188)/2, '@q189' = datalength(@q189)/2, '@q190' = datalength(@q190)/2, 
  2008.             '@q191' = datalength(@q191)/2, '@q192' = datalength(@q192)/2, '@q193' = datalength(@q193)/2, '@q194' = datalength(@q194)/2, '@q195' = datalength(@q195)/2, '@q196' = datalength(@q196)/2, '@q197' = datalength(@q197)/2, '@q198' = datalength(@q198)/2, '@q199' = datalength(@q199)/2, '@q200' = datalength(@q200)/2, 
  2009.             '@q201' = datalength(@q201)/2, '@q202' = datalength(@q202)/2, '@q203' = datalength(@q203)/2, '@q204' = datalength(@q204)/2, '@q205' = datalength(@q205)/2, '@q206' = datalength(@q206)/2, '@q207' = datalength(@q207)/2, '@q208' = datalength(@q208)/2, '@q209' = datalength(@q209)/2, '@q210' = datalength(@q210)/2, 
  2010.             '@q211' = datalength(@q211)/2, '@q212' = datalength(@q212)/2, '@q213' = datalength(@q213)/2, '@q214' = datalength(@q214)/2, '@q215' = datalength(@q215)/2, '@q216' = datalength(@q216)/2, '@q217' = datalength(@q217)/2, '@q218' = datalength(@q218)/2, '@q219' = datalength(@q219)/2, '@q220' = datalength(@q220)/2, 
  2011.             '@q221' = datalength(@q221)/2, '@q222' = datalength(@q222)/2, '@q223' = datalength(@q223)/2, '@q224' = datalength(@q224)/2, '@q225' = datalength(@q225)/2, '@q226' = datalength(@q226)/2, '@q227' = datalength(@q227)/2, '@q228' = datalength(@q228)/2, '@q229' = datalength(@q229)/2, '@q230' = datalength(@q230)/2, 
  2012.             '@q231' = datalength(@q231)/2, '@q232' = datalength(@q232)/2, '@q233' = datalength(@q233)/2, '@q234' = datalength(@q234)/2, '@q235' = datalength(@q235)/2, '@q236' = datalength(@q236)/2, '@q237' = datalength(@q237)/2, '@q238' = datalength(@q238)/2, '@q239' = datalength(@q239)/2, '@q240' = datalength(@q240)/2, 
  2013.             '@q241' = datalength(@q241)/2, '@q242' = datalength(@q242)/2, '@q243' = datalength(@q243)/2, '@q244' = datalength(@q244)/2, '@q245' = datalength(@q245)/2, '@q246' = datalength(@q246)/2, '@q247' = datalength(@q247)/2, '@q248' = datalength(@q248)/2, '@q249' = datalength(@q249)/2, '@q250' = datalength(@q250)/2
  2014.  
  2015.         select @q1+@q2+@q3+@q4+@q5+@q6+@q7+@q8+@q9+@q10+
  2016.             @q11+@q12+@q13+@q14+@q15+@q16+@q17+@q18+@q19+@q20+
  2017.             @q21+@q22+@q23+@q24+@q25+@q26+@q27+@q28+@q29+@q30+
  2018.             @q31+@q32+@q33+@q34+@q35+@q36+@q37+@q38+@q39+@q40+
  2019.             @q41+@q42+@q43+@q44+@q45+@q46+@q47+@q48+@q49+@q50+
  2020.             @q51+@q52+@q53+@q54+@q55+@q56+@q57+@q58+@q59+@q60+
  2021.             @q61+@q62+@q63+@q64+@q65+@q66+@q67+@q68+@q69+@q70+
  2022.             @q71+@q72+@q73+@q74+@q75+@q76+@q77+@q78+@q79+@q80+
  2023.             @q81+@q82+@q83+@q84+@q85+@q86+@q87+@q88+@q89+@q90+
  2024.             @q91+@q92+@q93+@q94+@q95+@q96+@q97+@q98+@q99+@q100+
  2025.             @q101+@q102+@q103+@q104+@q105+@q106+@q107+@q108+@q109+@q110+
  2026.             @q111+@q112+@q113+@q114+@q115+@q116+@q117+@q118+@q119+@q120+
  2027.             @q121+@q122+@q123+@q124+@q125+@q126+@q127+@q128+@q129+@q130+
  2028.             @q131+@q132+@q133+@q134+@q135+@q136+@q137+@q138+@q139+@q140+
  2029.             @q141+@q142+@q143+@q144+@q145+@q146+@q147+@q148+@q149+@q150+
  2030.             @q151+@q152+@q153+@q154+@q155+@q156+@q157+@q158+@q159+@q160+
  2031.             @q161+@q162+@q163+@q164+@q165+@q166+@q167+@q168+@q169+@q170+
  2032.             @q171+@q172+@q173+@q174+@q175+@q176+@q177+@q178+@q179+@q180+
  2033.             @q181+@q182+@q183+@q184+@q185+@q186+@q187+@q188+@q189+@q190+
  2034.             @q191+@q192+@q193+@q194+@q195+@q196+@q197+@q198+@q199+@q200+
  2035.             @q201+@q202+@q203+@q204+@q205+@q206+@q207+@q208+@q209+@q210+
  2036.             @q211+@q212+@q213+@q214+@q215+@q216+@q217+@q218+@q219+@q220+
  2037.             @q221+@q222+@q223+@q224+@q225+@q226+@q227+@q228+@q229+@q230+
  2038.             @q231+@q232+@q233+@q234+@q235+@q236+@q237+@q238+@q239+@q240+
  2039.             @q241+@q242+@q243+@q244+@q245+@q246+@q247+@q248+@q249+@q250
  2040.     end
  2041.     
  2042.     return 0
  2043. Error:
  2044.     return 1
  2045. end
  2046. go
  2047. exec sp_MS_marksystemobject N'dbo.sp_execresultset'
  2048. go
  2049.  
  2050. raiserror('Creating procedure sp_MSispulldistributionjobnamegenerated', 0,1) with nowait
  2051. go
  2052. --
  2053. -- Name: sp_MSispulldistributionjobnamegenerated
  2054. --
  2055. -- Descriptions: This procedure checks whether a given job id corresponds to
  2056. --               a pull distribution agent job with a name generated by replication. 
  2057. --               If so, a return value of zero will be returned, otherwise
  2058. --               a value of one will be returned to the caller.
  2059. -- 
  2060. -- Notes: 1) For this procedure to be effective, it must match the current
  2061. --           pull distribution agent name generation algorithm. Note that the 
  2062. --           algorithm used for matching auto-generated job name is not 
  2063. --           exact. (See sp_addpullsubscription_agent replsys.sql)
  2064. --        2) This procedure is supposed to be executed at the subscriber
  2065. --           database. The subscriber server name and subscriber database
  2066. --           name for contructing the generated job name are obtained via
  2067. --           the serverproperty('ServerName') and the db_name() functions. 
  2068. --
  2069. -- Parameters: @publisher     sysname
  2070. --             @publisher_db  sysname
  2071. --             @publication   sysname (This can be null for shared agent)
  2072. --             @job_id        uniqueidentifier
  2073. --
  2074. -- Returns: 0 - If the specified jobid corresponds to a snapshot job with
  2075. --              a generated name.
  2076. --          1 - Otherwise
  2077. --
  2078. -- Security: This is an internal system procedure.
  2079. --
  2080. create procedure dbo.sp_MSispulldistributionjobnamegenerated (
  2081.     @publisher     sysname,
  2082.     @publisher_db  sysname,
  2083.     @publication   sysname,
  2084.     @job_id        uniqueidentifier
  2085.     )
  2086. as
  2087. begin
  2088.     set nocount on
  2089.  
  2090.     declare @generated_job_name nvarchar(4000)
  2091.     declare @generated_job_name_length int
  2092.     declare @job_name sysname
  2093.  
  2094.     select @job_name = null
  2095.     select @job_name = name
  2096.       from msdb.dbo.sysjobs_view 
  2097.      where job_id = @job_id
  2098.  
  2099.     if @job_name is null
  2100.     begin
  2101.         goto MISMATCH
  2102.     end
  2103.  
  2104.     -- First of all, make sure that the job is indeed a distribution agent
  2105.     -- job (there should be a step with Distribution as the subsystem in the 
  2106.     -- job)
  2107.     if not exists (select * 
  2108.                      from msdb.dbo.sysjobsteps
  2109.                     where job_id = @job_id
  2110.                       and upper(subsystem collate SQL_Latin1_General_CP1_CS_AS) = N'DISTRIBUTION')
  2111.     begin
  2112.         goto MISMATCH
  2113.     end
  2114.                     
  2115.     -- Pull distribution agent names are always generated with a guid
  2116.     select @generated_job_name = left(@publisher, 21) + N'-'
  2117.                                + left(@publisher_db, 21) + N'-'
  2118.                                + left(@publication, 21) + N'-'
  2119.                                + left(convert(nvarchar(4000),serverproperty('ServerName')), 21) + N'-'
  2120.                                + left(db_name(), 21) + N'-'
  2121.  
  2122.     select @generated_job_name_length = len(@generated_job_name)
  2123.  
  2124.     -- Try matching the prefix of the job name
  2125.     if left(@job_name, @generated_job_name_length) = @generated_job_name
  2126.     begin
  2127.         -- Checks if the tail end of the job name matches a hexadecimal guid 
  2128.         -- with embedded dashes
  2129.         if upper(right(@job_name, len(@job_name) - @generated_job_name_length) collate SQL_Latin1_General_CP1_CS_AS)
  2130.             like N'[0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F]-[0-9A-F][0-9A-F][0-9A-F][0-9A-F]-[0-9A-F][0-9A-F][0-9A-F][0-9A-F]-[0-9A-F][0-9A-F][0-9A-F][0-9A-F]-[0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F]'
  2131.         begin
  2132.             return 0
  2133.         end
  2134.         else
  2135.         begin
  2136.             goto MISMATCH
  2137.         end
  2138.     end
  2139.  
  2140. MISMATCH:
  2141.     if @job_name is not null
  2142.     begin
  2143.         raiserror(21695, -1, -1, @job_name)
  2144.     end
  2145.     return 1
  2146. end
  2147. go
  2148. exec sp_MS_marksystemobject N'dbo.sp_MSispulldistributionjobnamegenerated'
  2149.  
  2150. raiserror('Creating procedure sp_MSispullmergejobnamegenerated', 0,1) with nowait
  2151. go
  2152. --
  2153. -- Name: sp_MSispullmergejobnamegenerated
  2154. --
  2155. -- Descriptions: This procedure checks whether a given job id corresponds to
  2156. --               a pull merge agent job with a name generated by replication. 
  2157. --               If so, a return value of zero will be returned, otherwise
  2158. --               a value of one will be returned to the caller.
  2159. -- 
  2160. -- Notes: 1) For this procedure to be effective, it must match the current
  2161. --           pull merge agent name generation algorithm. Note that the 
  2162. --           algorithm used for matching auto-generated job name is not 
  2163. --           exact. (See sp_addmergepullsubscription_agent replsys.sql)
  2164. --        2) This procedure is supposed to be executed at the subscriber
  2165. --           database. The subscriber server name and subscriber database
  2166. --           name for contructing the generated job name are obtained via
  2167. --           the serverproperty('ServerName') and the db_name() functions. 
  2168. --
  2169. -- Parameters: @publisher     sysname
  2170. --             @publisher_db  sysname
  2171. --             @publication   sysname (This can be null for shared agent)
  2172. --             @job_id        uniqueidentifier
  2173. --
  2174. -- Returns: 0 - If the specified jobid corresponds to a snapshot job with
  2175. --              a generated name.
  2176. --          1 - Otherwise
  2177. --
  2178. -- Security: This is an internal system procedure.
  2179. --
  2180. create procedure dbo.sp_MSispullmergejobnamegenerated (
  2181.     @publisher    sysname,
  2182.     @publisher_db sysname,
  2183.     @publication  sysname,
  2184.     @job_id       uniqueidentifier
  2185.     )
  2186. as
  2187. begin
  2188.     set nocount on
  2189.     
  2190.     declare @generated_job_name nvarchar(4000)
  2191.     declare @generated_job_name_length int
  2192.     declare @job_name sysname
  2193.  
  2194.     select @job_name = null
  2195.     select @job_name = name
  2196.       from msdb.dbo.sysjobs_view
  2197.      where job_id = @job_id
  2198.  
  2199.     if @job_name = null
  2200.     begin
  2201.         goto MISMATCH
  2202.     end
  2203.     
  2204.     -- First of all, make sure that the given job is indeed a merge agent
  2205.     -- job (There should be a step with Distribution as the subsystem in the 
  2206.     -- job)
  2207.     if not exists (select * 
  2208.                      from msdb.dbo.sysjobsteps
  2209.                     where job_id = @job_id
  2210.                       and upper(subsystem collate SQL_Latin1_General_CP1_CS_AS) = N'MERGE')
  2211.     begin
  2212.         goto MISMATCH
  2213.     end
  2214.     
  2215.     -- Pull merge agent names are always generated with a - 0 extension
  2216.     select @generated_job_name = left(@publisher, 23) + N'-'
  2217.                                + left(@publisher_db, 23) + N'-'
  2218.                                + left(@publication, 23) + N'-'
  2219.                                + left(convert(nvarchar(4000),serverproperty('ServerName')), 23) + N'-'
  2220.                                + left(db_name(), 23) + N'- 0'
  2221.  
  2222.     if @job_name = @generated_job_name
  2223.     begin
  2224.         return 0
  2225.     end    
  2226.  
  2227. MISMATCH:
  2228.     if @job_name is not null
  2229.     begin
  2230.         raiserror(21695, -1, -1, @job_name)
  2231.     end
  2232.     return 1
  2233. end
  2234. go
  2235. exec sp_MS_marksystemobject 'dbo.sp_MSispullmergejobnamegenerated'
  2236.  
  2237. raiserror('Creating function fn_escapecmdshellsymbols', 0,1) with nowait
  2238. go
  2239. --
  2240. -- Name: fn_escapecmdshellsymbols
  2241. --
  2242. -- Descriptions: This function returns an escaped version of a given string
  2243. --               with carets ('^') added in front of all the special 
  2244. --               command shell symbols. In the W2K online help (Start->
  2245. --               Help->Index->Command Reference->Command Symbols...), the 
  2246. --               following symbols are listed as special command symbols:
  2247. --                 (N'%', N'<', N'>', N'|', N'&', N'(', N')', N'^', N'"')
  2248. --
  2249. -- Parameter: @command_string nvarchar(4000)
  2250. -- 
  2251. -- Example: select fn_escapecmdshellsymbols(N'The % quick < brown > dog | jumps & over ( the ) lazy ^ fox.') 
  2252. --             will return 
  2253. --    
  2254. --    The ^% quick ^< brown ^> dog ^| jumps ^& over ^( the ^) lazy ^^ fox
  2255. --
  2256. -- Security: This function is granted to public
  2257. --
  2258. create function system_function_schema.fn_escapecmdshellsymbols(
  2259.     @command_string nvarchar(4000)
  2260.     ) returns nvarchar(4000)
  2261. as
  2262. begin
  2263.     declare @escaped_command_string nvarchar(4000),
  2264.             @curr_char nvarchar(1),
  2265.             @curr_char_index int    
  2266.     select @escaped_command_string = N'',
  2267.            @curr_char = N'', 
  2268.            @curr_char_index = 1
  2269.     while @curr_char_index <= len(@command_string)
  2270.     begin
  2271.         select @curr_char = substring(@command_string, @curr_char_index, 1) 
  2272.         if @curr_char in (N'%', N'<', N'>', N'|', N'&', N'(', N')', N'^', N'"')
  2273.         begin
  2274.             select @escaped_command_string = @escaped_command_string + N'^'
  2275.         end
  2276.         select @escaped_command_string = @escaped_command_string + @curr_char
  2277.         select @curr_char_index = @curr_char_index + 1 
  2278.     end
  2279.     return @escaped_command_string
  2280. end
  2281. go
  2282. grant execute on system_function_schema.fn_escapecmdshellsymbols to public
  2283.  
  2284. raiserror('Creating function fn_escapecmdshellsymbolsremovequotes', 0,1) with nowait
  2285. go
  2286. --
  2287. -- Name: fn_escapecmdshellsymbolsremovequotes
  2288. --
  2289. -- Descriptions: The only difference between this function and 
  2290. --               fn_escapecmdshellsymbols is that "'s are removed from the 
  2291. --               resulting command line.
  2292. --
  2293. -- Parameter: @command_string nvarchar(4000)
  2294. -- 
  2295. -- Security: This function is granted to public
  2296. --
  2297. create function system_function_schema.fn_escapecmdshellsymbolsremovequotes(
  2298.     @command_string nvarchar(4000)
  2299.     ) returns nvarchar(4000)
  2300. as
  2301. begin
  2302.     declare @escaped_command_string nvarchar(4000),
  2303.             @curr_char nvarchar(1),
  2304.             @curr_char_index int    
  2305.     select @escaped_command_string = N'',
  2306.            @curr_char = N'', 
  2307.            @curr_char_index = 1
  2308.     while @curr_char_index <= len(@command_string)
  2309.     begin
  2310.         select @curr_char = substring(@command_string, @curr_char_index, 1) 
  2311.         if @curr_char in (N'%', N'<', N'>', N'|', N'&', N'(', N')', N'^')
  2312.         begin
  2313.             select @escaped_command_string = @escaped_command_string + N'^'
  2314.         end
  2315.         if @curr_char <> '"'
  2316.         begin
  2317.             select @escaped_command_string = @escaped_command_string + @curr_char
  2318.         end
  2319.         select @curr_char_index = @curr_char_index + 1 
  2320.     end
  2321.     return @escaped_command_string
  2322. end
  2323. go
  2324. grant execute on system_function_schema.fn_escapecmdshellsymbolsremovequotes to public
  2325.  
  2326. print ''
  2327. print 'Creating function fn_repltrimleadingzerosinhexstr'
  2328. go
  2329. -- 
  2330. -- Name: fn_repltrimleadingzerosinhexstr
  2331. --
  2332. -- Description: This function is used for trimming the leading zeros 
  2333. --              of a 32-bit hexadecimal string. For example,
  2334. --              select fn_repltrimleadingzerosinhexstr('0000abcd') would 
  2335. --              yield 'abcd'. A notable special case would be select
  2336. --              fn_repltrimleadingzerosinhexstr('00000000') which yields
  2337. --              the string '0' instead of ''.
  2338. --
  2339. -- Parameter:   @hexstr  nchar(8) - @hexstr is expected to be a full 
  2340. --              hexadecimal representation of a 32-bit integer without the
  2341. --              0x prefix
  2342. --
  2343. -- Notes: 
  2344. --
  2345. -- Returns:     nvarchar(8)
  2346. -- 
  2347. -- Security:    Execute permission of this function is granted to public.
  2348. --
  2349. create function system_function_schema.fn_repltrimleadingzerosinhexstr (
  2350.     @hexstr nchar(8)
  2351.     ) returns nvarchar(8)
  2352. as
  2353. begin
  2354.     declare @trimmed_hexstr nvarchar(8),
  2355.             @i int    
  2356.     select @i = 1
  2357.     while @i < 8
  2358.     begin
  2359.         if substring(@hexstr,@i,1) <> N'0'
  2360.             break;
  2361.         select @i = @i + 1
  2362.     end    
  2363.     select @trimmed_hexstr = substring(@hexstr,@i,8-@i+1)
  2364.     return @trimmed_hexstr
  2365. end
  2366. go
  2367. grant execute on system_function_schema.fn_repltrimleadingzerosinhexstr to public
  2368.  
  2369. print ''
  2370. print 'Creating function fn_replinttobitstring'
  2371. go
  2372. --
  2373. -- Name: fn_replinttobitstring
  2374. -- 
  2375. -- Description: This function returns the bit pattern in string format for 
  2376. --              the specified 32-bit integer. For example, select 
  2377. --              fn_replinttobitstring(0x80000001) would yield
  2378. --              '10000000000000000000000000000001'
  2379. --
  2380. -- Parameter:   @number int
  2381. --
  2382. -- Returns:     char(32)
  2383. --
  2384. -- Security:    Execute permission of this function is granted to public.
  2385. --
  2386. create function system_function_schema.fn_replinttobitstring(
  2387.     @number int
  2388.     ) returns char(32)
  2389. as
  2390. begin
  2391.  
  2392.     declare @bitstring nvarchar(32)
  2393.  
  2394.     if (@number & 0x80000000) <> 0 select @bitstring = '1' else select @bitstring = '0'
  2395.     if (@number & 0x40000000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2396.     if (@number & 0x20000000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2397.     if (@number & 0x10000000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2398.     if (@number & 0x08000000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2399.     if (@number & 0x04000000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2400.     if (@number & 0x02000000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2401.     if (@number & 0x01000000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2402.     if (@number & 0x00800000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2403.     if (@number & 0x00400000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2404.     if (@number & 0x00200000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2405.     if (@number & 0x00100000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2406.     if (@number & 0x00080000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2407.     if (@number & 0x00040000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2408.     if (@number & 0x00020000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2409.     if (@number & 0x00010000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2410.     if (@number & 0x00008000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2411.     if (@number & 0x00004000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2412.     if (@number & 0x00002000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2413.     if (@number & 0x00001000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2414.     if (@number & 0x00000800) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2415.     if (@number & 0x00000400) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2416.     if (@number & 0x00000200) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2417.     if (@number & 0x00000100) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2418.     if (@number & 0x00000080) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2419.     if (@number & 0x00000040) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2420.     if (@number & 0x00000020) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2421.     if (@number & 0x00000010) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2422.     if (@number & 0x00000008) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2423.     if (@number & 0x00000004) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2424.     if (@number & 0x00000002) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2425.     if (@number & 0x00000001) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  2426.  
  2427.     return @bitstring
  2428. end
  2429. go
  2430. grant execute on system_function_schema.fn_replinttobitstring to public
  2431.  
  2432. print ''
  2433. print 'Creating function fn_replbitstringtoint'
  2434. go
  2435. --
  2436. -- Name: fn_replbitstringtoint
  2437. --
  2438. -- Description: This function returns the integer value of the specified
  2439. --              32-bit bit pattern in string format.
  2440. --
  2441. -- Parameter:   @bitstring char(32)
  2442. --
  2443. -- Notes:
  2444. --
  2445. -- Returns:     int
  2446. --
  2447. -- Security:    Execute permission of this function is granted to public.
  2448. --
  2449. create function system_function_schema.fn_replbitstringtoint(
  2450.     @bitstring char(32)
  2451.     ) returns int
  2452. as
  2453. begin
  2454.     declare @number int 
  2455.     select @number = 0
  2456.     if (substring(@bitstring,1,1) = '1') select @number = @number | 0x80000000 
  2457.     if (substring(@bitstring,2,1) = '1') select @number = @number | 0x40000000 
  2458.     if (substring(@bitstring,3,1) = '1') select @number = @number | 0x20000000 
  2459.     if (substring(@bitstring,4,1) = '1') select @number = @number | 0x10000000 
  2460.     if (substring(@bitstring,5,1) = '1') select @number = @number | 0x08000000 
  2461.     if (substring(@bitstring,6,1) = '1') select @number = @number | 0x04000000 
  2462.     if (substring(@bitstring,7,1) = '1') select @number = @number | 0x02000000 
  2463.     if (substring(@bitstring,8,1) = '1') select @number = @number | 0x01000000 
  2464.     if (substring(@bitstring,9,1) = '1') select @number = @number | 0x00800000 
  2465.     if (substring(@bitstring,10,1) = '1') select @number = @number | 0x00400000 
  2466.     if (substring(@bitstring,11,1) = '1') select @number = @number | 0x00200000 
  2467.     if (substring(@bitstring,12,1) = '1') select @number = @number | 0x00100000 
  2468.     if (substring(@bitstring,13,1) = '1') select @number = @number | 0x00080000 
  2469.     if (substring(@bitstring,14,1) = '1') select @number = @number | 0x00040000 
  2470.     if (substring(@bitstring,15,1) = '1') select @number = @number | 0x00020000 
  2471.     if (substring(@bitstring,16,1) = '1') select @number = @number | 0x00010000 
  2472.     if (substring(@bitstring,17,1) = '1') select @number = @number | 0x00008000 
  2473.     if (substring(@bitstring,18,1) = '1') select @number = @number | 0x00004000 
  2474.     if (substring(@bitstring,19,1) = '1') select @number = @number | 0x00002000 
  2475.     if (substring(@bitstring,20,1) = '1') select @number = @number | 0x00001000 
  2476.     if (substring(@bitstring,21,1) = '1') select @number = @number | 0x00000800 
  2477.     if (substring(@bitstring,22,1) = '1') select @number = @number | 0x00000400 
  2478.     if (substring(@bitstring,23,1) = '1') select @number = @number | 0x00000200 
  2479.     if (substring(@bitstring,24,1) = '1') select @number = @number | 0x00000100 
  2480.     if (substring(@bitstring,25,1) = '1') select @number = @number | 0x00000080 
  2481.     if (substring(@bitstring,26,1) = '1') select @number = @number | 0x00000040 
  2482.     if (substring(@bitstring,27,1) = '1') select @number = @number | 0x00000020 
  2483.     if (substring(@bitstring,28,1) = '1') select @number = @number | 0x00000010 
  2484.     if (substring(@bitstring,29,1) = '1') select @number = @number | 0x00000008 
  2485.     if (substring(@bitstring,30,1) = '1') select @number = @number | 0x00000004 
  2486.     if (substring(@bitstring,31,1) = '1') select @number = @number | 0x00000002 
  2487.     if (substring(@bitstring,32,1) = '1') select @number = @number | 0x00000001 
  2488.     return @number
  2489. end
  2490. go
  2491. grant execute on system_function_schema.fn_replbitstringtoint to public
  2492.  
  2493. print ''
  2494. print 'Creating function fn_replrotr'
  2495. go
  2496. --
  2497. -- Name: fn_replrotr
  2498. --
  2499. -- Description: This is just a T-SQL implementation of the C function
  2500. --              _rotr().
  2501. --
  2502. -- Parameter:  @number int
  2503. --             @shift  int
  2504. --
  2505. -- Notes:      The effective shift will the positive remainder of @shift 
  2506. --             divided by 32. _rotl() can be implemented by passing in 
  2507. --             a negative shift.
  2508. --
  2509. -- Returns:    int
  2510. --
  2511. -- Security:   Execute permission of this function is granted to public.
  2512. --
  2513. create function system_function_schema.fn_replrotr(
  2514.     @number int,
  2515.     @shift int
  2516.     ) returns int
  2517. as
  2518. begin
  2519.     declare @bitstring char(32)
  2520.     select @shift = @shift % 32
  2521.     if @shift < 0
  2522.         select @shift = @shift + 32
  2523.  
  2524.     if (@shift != 0)
  2525.     begin
  2526.         select @bitstring = fn_replinttobitstring(@number)   
  2527.         select @bitstring = substring(@bitstring,32-@shift+1,@shift) + substring(@bitstring,1,32-@shift) 
  2528.         select @number = fn_replbitstringtoint(@bitstring)
  2529.     end
  2530.     return @number
  2531. end
  2532. go
  2533. grant execute on system_function_schema.fn_replrotr to public
  2534.  
  2535.  
  2536. print ''
  2537. print 'Creating function fn_replgenerateshorterfilenameprefix'
  2538. go
  2539. --
  2540. -- Name: fn_replgenerateshorterfilenameprefix
  2541. --
  2542. -- Description: This function mimics the algorithm used by the snapshot 
  2543. --              agent to shorten any overly long component of a publication
  2544. --              snapshot folder with "overly long" defined as more than
  2545. --              30 characters in length (as specified in the @truncated_len
  2546. --              parameter of this function). 
  2547. --                
  2548. -- Parameters:  @prefix nvarchar(4000)
  2549. --              @truncated_len int
  2550. --
  2551. -- Notes:
  2552. --
  2553. -- Returns: nvarchar(4000)
  2554. --
  2555. -- Security: Execute permission on this function is granted to public.
  2556. --
  2557. create function system_function_schema.fn_replgenerateshorterfilenameprefix(
  2558.     @prefix nvarchar(4000),
  2559.     @truncated_len int
  2560.     ) returns nvarchar(4000)
  2561. as
  2562. begin
  2563.     declare @HashValueIndex int,
  2564.             @HashValue int,
  2565.             @CurrentByte tinyint,
  2566.             @TruncatedString varbinary(8000),
  2567.             @i int,
  2568.             @TruncatedStringLen int,
  2569.             @prefix_to_be_returned nvarchar(4000)
  2570.  
  2571.     select @prefix_to_be_returned = @prefix
  2572.     if (len(@prefix) > @truncated_len)
  2573.     begin
  2574.         select @TruncatedString = convert(varbinary(8000),substring(@prefix,@truncated_len-8+1,len(@prefix)-@truncated_len+8))
  2575.         select @TruncatedStringLen = len(@TruncatedString)
  2576.         select @HashValue = 0
  2577.         select @i = 1
  2578.         select @HashValueIndex = 0
  2579.         while @i <= @TruncatedStringLen
  2580.         begin
  2581.             select @CurrentByte = convert(tinyint,substring(@TruncatedString,@i,1))
  2582.             select @HashValue = @HashValue ^ fn_replrotr(@CurrentByte, -(8*@HashValueIndex))
  2583.             select @HashValue = fn_replrotr(@HashValue, @HashValueIndex + 1)
  2584.             if @CurrentByte != 0
  2585.             begin
  2586.                 select @HashValueIndex = (@HashValueIndex + 1) % 4
  2587.             end
  2588.             select @i = @i + 1
  2589.         end
  2590.         select @prefix_to_be_returned = substring(@prefix,1,@truncated_len-8) 
  2591.         select @prefix_to_be_returned = @prefix_to_be_returned + lower(fn_repltrimleadingzerosinhexstr(substring(master.dbo.fn_varbintohexstr(convert(varbinary(4),@HashValue)) collate database_default,3,8)) collate database_default)
  2592.     end
  2593.     return @prefix_to_be_returned
  2594. end
  2595. go
  2596. grant execute on system_function_schema.fn_replgenerateshorterfilenameprefix to public      
  2597.  
  2598. print ''
  2599. print 'Creating function fn_replcomposepublicationsnapshotfolder'
  2600. go    
  2601. --
  2602. -- Name: fn_replcomposepublicationsnapshotfolder
  2603. --
  2604. -- Description: This mimics the algorithm used by the snapshot agent for 
  2605. --              composing the name of a publication's snapshot folder.
  2606. --
  2607. -- Parameters:  @publisher    sysname
  2608. --              @publisher_db sysname 
  2609. --              @publication  sysname
  2610. --
  2611. -- Notes: 
  2612. --
  2613. -- Returns: nvarchar(255)
  2614. --
  2615. -- Security: Execute permission of this function is granted to public.
  2616. --
  2617. create function system_function_schema.fn_replcomposepublicationsnapshotfolder(
  2618.     @publisher     sysname,
  2619.     @publisher_db  sysname,
  2620.     @publication   sysname
  2621. ) returns nvarchar(255)
  2622. as
  2623. begin
  2624.     declare @snapshot_folder_name nvarchar(255)
  2625.     
  2626.     select @snapshot_folder_name = fn_replgenerateshorterfilenameprefix(@publisher,30) collate database_default + N'_' +
  2627.                                    fn_replgenerateshorterfilenameprefix(@publisher_db,30) collate database_default + N'_' +
  2628.                                    fn_replgenerateshorterfilenameprefix(@publication,30) collate database_default
  2629.     return @snapshot_folder_name
  2630. end
  2631. go
  2632. grant execute on system_function_schema.fn_replcomposepublicationsnapshotfolder to public
  2633. go
  2634.  
  2635. --
  2636. -- Name: sp_MSdroparticleconstraints
  2637. --
  2638. -- Description: This procedure is used by the Distribution Agent to purge all
  2639. --              the existing check, PK, UK, and FK constraints on a table
  2640. --              article at the Subscriber.
  2641. --
  2642. -- Parameters:  @destination_object sysname (mandatory)
  2643. --              @destination_owner sysname (mandatory)
  2644. -- 
  2645. -- Returns: 0 - succeeded
  2646. --          1 - failed
  2647. -- 
  2648. -- Security: Procedural security check is done inside this procedure
  2649. --           to make sure that the caller is either a member of the db_owner
  2650. --           role of the subscriber database or a member of the sysadmin role
  2651. --           of the subscription server 
  2652. --
  2653. print ''
  2654. print 'Creating procedure sp_MSdroparticleconstraints'
  2655. go
  2656. create procedure dbo.sp_MSdroparticleconstraints (
  2657.     @destination_object sysname,
  2658.     @destination_owner sysname
  2659.     )
  2660. as
  2661. begin
  2662.     set nocount on
  2663.     declare @retcode      int,
  2664.             @objid        int,
  2665.             @constid      int,
  2666.             @drop_command nvarchar(4000),
  2667.             @qualified_tablename nvarchar(540),
  2668.             @publish_bit  int,
  2669.             @mergepublish_bit int
  2670.  
  2671.     
  2672.     select @retcode             = 0,
  2673.            @objid               = null,
  2674.            @constid             = null,
  2675.            @drop_command        = null,
  2676.            @qualified_tablename = null,
  2677.            @publish_bit         = 1,
  2678.            @mergepublish_bit    = 128
  2679.  
  2680.     -- Security check
  2681.     exec @retcode = sp_MSreplcheck_subscribe
  2682.     if @retcode<>0 or @@error<>0
  2683.         return 1
  2684.  
  2685.     -- Get object id of the target table
  2686.     select @objid = id 
  2687.       from sysobjects
  2688.      where name = @destination_object
  2689.        and (user_name(uid) = @destination_owner 
  2690.             or @destination_owner is null 
  2691.             or @destination_owner = N'')
  2692.  
  2693.     -- If the object is not at the subscriber, there isn't anything we 
  2694.     -- can(or need to)  do
  2695.     if @objid is null 
  2696.         return 0
  2697.  
  2698.     select @qualified_tablename = 
  2699.             N'['+replace(@destination_object,N']',N']]')+N']'
  2700.  
  2701.     if @destination_owner is not null and @destination_owner<>N''
  2702.     begin
  2703.         select @qualified_tablename = 
  2704.             N'['+replace(@destination_owner,N']',N']]')+N'].'+@qualified_tablename
  2705.     end
  2706.  
  2707.     -- Skip constraint dropping for republished article
  2708.     if exists (select * 
  2709.                  from sysobjects 
  2710.                 where id = @objid
  2711.                   and ((replinfo & @publish_bit <> 0) or
  2712.                        (replinfo & @mergepublish_bit <> 0)))
  2713.     begin
  2714.         return 0
  2715.     end
  2716.  
  2717.     declare hConst cursor local fast_forward for
  2718.      select constid 
  2719.        from sysconstraints 
  2720.       where id = @objid
  2721.       order by convert(int, objectproperty(constid,'IsForeignKey')) desc
  2722.     if @@error<>0
  2723.         return 1
  2724.  
  2725.     open hConst
  2726.     if @@error<>0
  2727.         return 1
  2728.     
  2729.     fetch hConst into @constid 
  2730.     while (@@fetch_status<>-1)
  2731.     begin
  2732.     
  2733.         if objectproperty(@constid,N'IsUniqueCnst') = 1 or
  2734.            objectproperty(@constid,N'IsPrimaryKey') = 1 or
  2735.            objectproperty(@constid,N'IsCheckCnst') = 1 or
  2736.            objectproperty(@constid,N'IsForeignKey') = 1
  2737.         begin
  2738.             select @drop_command = 
  2739.                 N'alter table '+@qualified_tablename+' drop constraint '+object_name(@constid)
  2740.             exec(@drop_command)
  2741.             if @@error <> 0
  2742.                 return 1
  2743.         end
  2744.         fetch hConst into @constid        
  2745.     end
  2746.     close hConst
  2747.     deallocate hConst
  2748.  
  2749.     return @retcode
  2750.  
  2751. end
  2752. go
  2753. exec sp_MS_marksystemobject sp_MSdroparticleconstraints
  2754. grant execute on sp_MSdroparticleconstraints to public 
  2755. --
  2756. -- Name: sp_MSacquireserverresourcefordynamicsnapshot
  2757. --
  2758. -- Description: This is a light-weight wrapper of sp_MSacuireApplicationLock
  2759. --              used by dynamic snapshot for governing the maximum number of
  2760. --              concurrent dynamic snapshot sessions for a merge publication.
  2761. --
  2762. -- Parameters: @publication sysname (mandatory)
  2763. --             @max_concurrent_dynamic_snapshots int (mandatory)
  2764. --
  2765. -- Security: Procedural security check is performed inside 
  2766. --           sp_MSacquireSlotLock to make sure that the caller is 
  2767. --           either sysadmin, db_owner, or replication agent.
  2768. --
  2769. print ''
  2770. print 'Creating procedure sp_MSacquireserverresourcefordynamicsnapshot'
  2771. go
  2772. create procedure dbo.sp_MSacquireserverresourcefordynamicsnapshot (
  2773.     @publication sysname,
  2774.     @max_concurrent_dynamic_snapshots int
  2775.     )
  2776. as
  2777. begin
  2778.     set nocount on
  2779.     declare @retcode int
  2780.     declare @pubid uniqueidentifier
  2781.     declare @process_name sysname
  2782.     select @retcode = 0
  2783.  
  2784.     -- security check
  2785.     exec @retcode = dbo.sp_MSreplcheck_publish
  2786.     if @@ERROR <> 0 or @retcode <> 0
  2787.         return 1
  2788.         
  2789.     if object_id('sysmergepublications') is null
  2790.     begin
  2791.         raiserror(20026, 16, -1, @publication)
  2792.         return (1) 
  2793.     end
  2794.  
  2795.     select @pubid = null
  2796.     select @pubid = pubid 
  2797.       from sysmergepublications
  2798.      where name = @publication 
  2799.        and publisher_db = db_name()
  2800.        and upper(publisher) = upper(@@servername)
  2801.              
  2802.     if @pubid is null   
  2803.     begin
  2804.         raiserror(20026, 16, -1, @publication)
  2805.         return (1) 
  2806.     end
  2807.  
  2808.     -- The following string construction will never overflow
  2809.     -- sysname
  2810.     select @process_name = N'ReplicationSnapshotAgent' + 
  2811.         convert(nvarchar(40), @pubid)     
  2812.  
  2813.     -- Acquire head of queue lock first
  2814.     exec @retcode = sp_MSacquireHeadofQueueLock
  2815.         @process_name = @process_name,
  2816.         @queue_timeout = 0,
  2817.         @no_result = 1
  2818.  
  2819.     if @@error<>0
  2820.         return (1)
  2821.  
  2822.     if @retcode<>0
  2823.         goto Failure
  2824.  
  2825.     exec @retcode = sp_MSacquireSlotLock 
  2826.         @process_name = @process_name,
  2827.         @concurrent_max = @max_concurrent_dynamic_snapshots    
  2828.     
  2829.     if @@error<>0
  2830.         return (1)
  2831.  
  2832. Failure:
  2833.  
  2834.     return @retcode
  2835. end
  2836. go
  2837. exec sp_MS_marksystemobject sp_MSacquireserverresourcefordynamicsnapshot
  2838. go
  2839. grant execute on sp_MSacquireserverresourcefordynamicsnapshot to public
  2840. go
  2841.  
  2842. -- 
  2843. -- Name: fn_replgetbinary8lodword
  2844. --
  2845. -- Description: This function will get the lower dword of
  2846. --              a given binary(8) value. For example:
  2847. --            
  2848. --              select fn_replgetbinary8lodword(0x0000000012345678)
  2849. --              will return the integer
  2850. --              0x12345678
  2851. --
  2852. -- Parameter: @binary8_value binary(8)
  2853. --
  2854. -- Returns: int
  2855. --
  2856. -- Security: Execute permission of this function is granted 
  2857. --           to public
  2858. --
  2859. print ''
  2860. print 'Creating function fn_replgetbinary8lodword'
  2861. go
  2862. create function system_function_schema.fn_replgetbinary8lodword (
  2863.     @binary8_value binary(8)
  2864.     ) returns int
  2865. as
  2866. begin
  2867.     declare @lodword int
  2868.     select @lodword = convert(int, substring(@binary8_value, 5, 4))
  2869.     return @lodword
  2870. end
  2871. go
  2872. grant execute on system_function_schema.fn_replgetbinary8lodword to public
  2873. go
  2874.  
  2875. -- 
  2876. -- Name: fn_replprepadbinary8
  2877. --
  2878. -- Description: This function is typically used by replication
  2879. --              stored procedures to add padding 0s in front
  2880. --              of a user-specified schema_option value. For
  2881. --              example:
  2882. --
  2883. --              select fn_replprepadbinary8(0x01) will return
  2884. --
  2885. --              0x0000000000000001
  2886. --
  2887. -- Parameter: @varbinary8_value varbinary(8)
  2888. --
  2889. -- Returns: binary(8) 
  2890. --              
  2891. -- Security: Execute permission of this function is granted
  2892. --           to public
  2893. --               
  2894. print ''
  2895. print 'Creating function fn_replprepadbinary8'
  2896. go
  2897. create function system_function_schema.fn_replprepadbinary8 (
  2898.     @varbinary8_value varbinary(8)
  2899.     ) returns binary(8)
  2900. as
  2901. begin
  2902.     declare @padded_value binary(8)
  2903.     select @padded_value = 
  2904.         substring(0x0000000000000000, 
  2905.                   1, 
  2906.                   8 - datalength(@varbinary8_value)) 
  2907.         + @varbinary8_value
  2908.     return @padded_value
  2909. end
  2910. go
  2911. grant execute on system_function_schema.fn_replprepadbinary8 to public
  2912. go
  2913.  
  2914. --
  2915. -- Name: fn_replmakestringliteral
  2916. --
  2917. -- Description: This is a simple helper function for generating the unicode string 
  2918. --              literal representation of a given string. For example
  2919. --              
  2920. --                  select fn_replmakestringliteral('string''literal')
  2921. -- 
  2922. --              will return
  2923. --
  2924. --                  N'string''literal'
  2925. --
  2926. -- Parameter: @string nvarchar(4000)
  2927. -- 
  2928. -- Returns: nvarchar(4000)
  2929. --
  2930. -- Security: Public access
  2931. --
  2932. raiserror('Creating function fn_replmakestringliteral', 0,1)
  2933. go
  2934. create function system_function_schema.fn_replmakestringliteral (
  2935.     @string nvarchar(4000)
  2936.     ) returns nvarchar(4000)
  2937. as
  2938. begin
  2939.     declare @string_literal nvarchar(4000)
  2940.     select @string_literal = N'N''' + replace(@string, '''', '''''') + N''''
  2941.     return @string_literal
  2942. end
  2943. go
  2944. grant execute on system_function_schema.fn_replmakestringliteral to public
  2945. go
  2946.  
  2947. -- 
  2948. -- Name: sp_MSgettranlastupdatedtime
  2949. --
  2950. -- Description: This procedure retrieves the last updated time from the 
  2951. --              subscriber database for a transactional/snapshot 
  2952. --              subscription.    
  2953. --
  2954. -- Parameters: @publisher sysname (mandatory)
  2955. --             @publisher_db sysname (mandatory)
  2956. --             @publication sysname (mandatory)
  2957. --             @subscription_type int (mandatory)
  2958. -- Notes: This procedure should always be called internally by 
  2959. --        sp_MSgetlastupdatedtime
  2960. --
  2961. -- Result: 'last updated time' nvarchar
  2962. --
  2963. -- Returns 0 - succeeded
  2964. --         1 - failed
  2965. --
  2966. -- Security: Sysadmin access only 
  2967. --
  2968. print 'Creating procedure sp_MSgettranlastupdatedtime'
  2969. print ''
  2970. go
  2971. create procedure sp_MSgettranlastupdatedtime(
  2972.     @publisher sysname,
  2973.     @publisher_db sysname,
  2974.     @publication sysname,
  2975.     @subscription_type int
  2976.     )
  2977. as
  2978. begin
  2979.     set nocount on
  2980.     declare @last_updated_time nvarchar(40)
  2981.     
  2982.     select @last_updated_time = null
  2983.  
  2984.     if object_id('MSreplication_subscriptions') is null
  2985.     begin
  2986.         select 'last updated time' = @last_updated_time
  2987.         raiserror(21384, 16, -1)        
  2988.         return 1
  2989.     end
  2990.     
  2991.     -- For subscriptions sharing an agent, 
  2992.     -- the control may not be passing in the publication
  2993.     -- name. 
  2994.     select @last_updated_time = convert(nvarchar(12), time, 112) +
  2995.                                 substring(convert(nvarchar(24), time, 121), 11,13)
  2996.       from MSreplication_subscriptions    
  2997.      where upper(@publisher) = upper(publisher)
  2998.        and @publisher_db = publisher_db
  2999.        and (((@publication is null or @publication = N'') and independent_agent = 0)
  3000.             or (@publication = publication))
  3001.        and @subscription_type = subscription_type
  3002.  
  3003.     select 'last updated time' = @last_updated_time
  3004.  
  3005.     if @last_updated_time is null
  3006.     begin
  3007.         raiserror(21384, 16, -1)
  3008.         return 1
  3009.     end
  3010.     return 0
  3011. end
  3012. go
  3013. exec sp_MS_marksystemobject 'sp_MSgettranlastupdatedtime'
  3014.  
  3015. -- 
  3016. -- Name: sp_MSgetmergelastupdatedtime
  3017. -- 
  3018. -- Description: This procedure retrieves the last updated time from the
  3019. --              subscriber database for a merge subscription.
  3020. --
  3021. -- Parameters: @publisher sysname (mandatory)
  3022. --             @publisher_db sysname (mandatory)
  3023. --             @publication sysname (mandatory)
  3024. --             @subscription_type int (mandatory)
  3025. -- Notes: This procedure should always be called internally by 
  3026. --        sp_MSgetlastupdatedtime
  3027. --
  3028. -- Result: 'last updated time' nvarchar
  3029. --
  3030. -- Returns: 0 - succeeded
  3031. --          1 - failed
  3032. --
  3033. -- Security: Sysadmin access only
  3034. --
  3035. print 'Creating procedure sp_MSgetmergelastupdatedtime'
  3036. print ''
  3037. go
  3038. create procedure sp_MSgetmergelastupdatedtime(
  3039.     @publisher sysname,
  3040.     @publisher_db sysname,
  3041.     @publication sysname,
  3042.     @subscription_type int
  3043.     )
  3044. as
  3045. begin
  3046.     set nocount on
  3047.     declare @last_updated_time nvarchar(40)
  3048.     declare @last_updated_datetime datetime
  3049.  
  3050.     select @last_updated_datetime = null
  3051.     select @last_updated_time = null
  3052.     
  3053.     if object_id('sysmergesubscriptions') is null or
  3054.        object_id('sysmergepublications') is null
  3055.     begin
  3056.         select 'last updated time' = @last_updated_time
  3057.         raiserror(21384, 16, -1)        
  3058.         return 1
  3059.     end
  3060.  
  3061.     select @last_updated_datetime = last_sync_date 
  3062.       from sysmergesubscriptions sms
  3063.     inner join sysmergepublications smp
  3064.         on sms.pubid = smp.pubid     
  3065.      where upper(@@servername) = upper(sms.subscriber_server)
  3066.        and sms.db_name =  db_name()
  3067.        and sms.subscription_type = @subscription_type
  3068.        and upper(smp.publisher) = upper(publisher)
  3069.        and smp.publisher_db = @publisher_db
  3070.        and smp.name = @publication
  3071.  
  3072.     if @last_updated_datetime is not null
  3073.     begin
  3074.         select @last_updated_time = convert(nvarchar(12), @last_updated_datetime, 112) +
  3075.                   substring(convert(nvarchar(24), @last_updated_datetime, 121), 11,13)
  3076.     end
  3077.  
  3078.     select 'last updated time' = @last_updated_time
  3079.  
  3080.     if @last_updated_time is null
  3081.     begin
  3082.         raiserror(21384, 16, -1)
  3083.         return 1
  3084.     end
  3085.     return 0
  3086. end
  3087. go
  3088. exec sp_MS_marksystemobject 'sp_MSgetmergelastupdatedtime'
  3089.  
  3090. --
  3091. -- Name: sp_MSgetlastupdatedtime
  3092. -- 
  3093. -- Description: This procedure is used internally by the ActiveX controls
  3094. --              to retrieve the last updated time of the specified 
  3095. --              subscription. 
  3096. --  
  3097. -- Parameters: @publisher sysname (mandatory)
  3098. --             @publisher_db sysname (mandatory)
  3099. --             @publication sysname (mandatory)
  3100. --             @subscription_type int (mandatory)
  3101. --             @publication_type int (mandatory) (1 - transactional/snapshot
  3102. --                                                2 - merge)
  3103. -- Returns: 0 - succeeded
  3104. --          1 - failed
  3105. --
  3106. -- Result: 'last updated time' nvarchar 
  3107. --
  3108. -- Security: Execute permission of this stored procedure is granted to public
  3109. --           but security check is performed inside the procedure to make
  3110. --           sure that only dbo of the subscriber database and server admin
  3111. --           can retrieve the last updated time successfully. 
  3112. --
  3113. print 'Creating procedure sp_MSgetlastupdatedtime'
  3114. print ''
  3115. go
  3116. create procedure sp_MSgetlastupdatedtime(
  3117.     @publisher sysname,
  3118.     @publisher_db sysname,
  3119.     @publication sysname,
  3120.     @subscription_type int,
  3121.     @publication_type int  -- 1 - transactional/snapshot, 2 - merge
  3122.     )
  3123. as
  3124. begin
  3125.     set nocount on
  3126.     declare @retcode int
  3127.     select @retcode = 0
  3128.  
  3129.     -- Security check
  3130.     exec @retcode = sp_MSreplcheck_subscribe    
  3131.     if @retcode<>0 or @@error<>0
  3132.         return 1
  3133.  
  3134.     if @publication_type in (0,1)
  3135.     begin
  3136.         exec @retcode = sp_MSgettranlastupdatedtime @publisher,
  3137.                                                     @publisher_db,
  3138.                                                     @publication,
  3139.                                                     @subscription_type
  3140.     end
  3141.     else
  3142.     begin
  3143.         exec @retcode = sp_MSgetmergelastupdatedtime @publisher,
  3144.                                                      @publisher_db,
  3145.                                                      @publication,
  3146.                                                      @subscription_type
  3147.     end
  3148.     return @retcode
  3149. end
  3150. go
  3151. exec sp_MS_marksystemobject 'sp_MSgetlastupdatedtime'
  3152.  
  3153. --
  3154. -- Name: fn_repladjustcolumnmap
  3155. --
  3156. -- Description: This function adjusts the bitmap for subscriber/destination tables
  3157. -- that have been altered and the relative column order do not match the actual
  3158. -- column id. The column_updated() bitmap for such tables need to be adjusted to
  3159. -- reflect relative column order before sending them to publisher 
  3160. --
  3161. -- Parameters: 
  3162. --    @objid    int - destination table object id
  3163. --     ,@total_col int - total number of columns in the table
  3164. --     ,@inmap varbinary(4000) input bitmap that is based on actual column id
  3165. --
  3166. -- Returns: varbinary(4000) output column that is based on relative column order
  3167. --
  3168. -- Security: Execute permission of this function is granted to public
  3169. -- 
  3170. raiserror('Creating function fn_repladjustcolumnmap', 0,1)
  3171. go
  3172. create function system_function_schema.fn_repladjustcolumnmap
  3173. (
  3174.     @objid    int
  3175.     ,@total_col int
  3176.     ,@inmap varbinary(4000)
  3177. returns varbinary(4000)
  3178. as
  3179. begin
  3180.     declare @colmap table (relativeorder int identity(1,1), colid int)
  3181.     declare
  3182.         @outmap varbinary(4000)
  3183.         ,@relpos int
  3184.         ,@colid int
  3185.         ,@bytepos int
  3186.         ,@bitpos int
  3187.         ,@num_bytes int
  3188.  
  3189.     --
  3190.     -- initialize
  3191.     --
  3192.     select @outmap = 0
  3193.     insert into @colmap (colid)
  3194.         select colid from syscolumns where id = @objid order by colid
  3195.     if (@@error != 0)
  3196.     begin
  3197.         return cast(NULL as varbinary(4000))
  3198.     end
  3199.  
  3200.     --
  3201.     -- for each column in the column map
  3202.     --
  3203.     declare #colmap_cursor cursor local fast_forward for 
  3204.         select relativeorder, colid from @colmap 
  3205.         order by relativeorder
  3206.     for read only
  3207.  
  3208.     open #colmap_cursor
  3209.     fetch #colmap_cursor into @relpos, @colid
  3210.     while (@@fetch_status = 0)
  3211.     begin
  3212.         --
  3213.         -- select the absolute column position
  3214.         --
  3215.         select @bytepos = 1 + ((@colid-1) / 8)
  3216.             ,@bitpos =  power(2, (@colid-1) % 8 ) 
  3217.  
  3218.         if (substring(@inmap, @bytepos, 1) & @bitpos = @bitpos)
  3219.         begin
  3220.             --
  3221.             -- set the relative position for this column in the output
  3222.             --
  3223.             select @bytepos = 1 + ((@relpos-1) / 8)
  3224.                 ,@bitpos =  power(2, (@relpos-1) % 8 )
  3225.                 ,@num_bytes = @total_col / 8 + 1
  3226.  
  3227.             select @outmap = substring(@outmap, 1, (@bytepos - 1)) + 
  3228.                 (convert(binary(1), substring(@outmap, @bytepos, 1) | convert(tinyint,@bitpos))) + 
  3229.                 substring(@outmap, (@bytepos + 1), (@num_bytes - @bytepos))
  3230.         end
  3231.  
  3232.         -- fetch next column mapping
  3233.         fetch #colmap_cursor into @relpos, @colid        
  3234.     end
  3235.     close #colmap_cursor
  3236.     deallocate #colmap_cursor
  3237.  
  3238.     return @outmap
  3239. end
  3240. go
  3241. grant execute on system_function_schema.fn_repladjustcolumnmap to public
  3242.  
  3243. --
  3244. -- Name: fn_replquotename
  3245. --
  3246. -- Description: This is simply a more complete implementation of quote_name()
  3247. --              that can handle longer strings. Note that this function is
  3248. --              hard-coded to do square-bracket quoting only.
  3249. --
  3250. -- Parameter: @string nvarchar(1998)
  3251. --
  3252. -- Returns: nvarchar(4000)
  3253. --
  3254. -- Security: Execute permission of this function is granted to public
  3255. -- 
  3256. print 'Creating function fn_replquotename'
  3257. print ''
  3258. go
  3259. create function system_function_schema.fn_replquotename(
  3260.     @string nvarchar(1998)
  3261.     ) returns nvarchar(4000)
  3262. begin
  3263.  
  3264.     declare @resulting_string nvarchar(4000)
  3265.     declare @string_len int 
  3266.     declare @char nchar(1)
  3267.     declare @index int    
  3268.  
  3269.     select @resulting_string = null
  3270.     if @string is not null
  3271.     begin
  3272.         select @string_len = len(@string)
  3273.         select @index = 1
  3274.  
  3275.         select @resulting_string = N'['
  3276.  
  3277.         while @index <=  @string_len
  3278.         begin
  3279.             select @char = substring(@string, @index, 1)
  3280.  
  3281.             select @resulting_string = @resulting_string + @char
  3282.             if @char = N']'
  3283.             begin
  3284.                 select @resulting_string = @resulting_string + N']'
  3285.             end
  3286.  
  3287.             select @index = @index + 1
  3288.         end
  3289.         select @resulting_string = @resulting_string + N']'
  3290.     end
  3291.     return @resulting_string
  3292. end
  3293. go
  3294.  
  3295. -- 
  3296. -- Name: fn_chariswhitespace
  3297. -- 
  3298. -- Description: This is a very simple function that checks whether a given
  3299. --              character is a white-space.
  3300. -- 
  3301. -- Parameters: @char nchar(1)
  3302. -- 
  3303. -- Notes:
  3304. -- 
  3305. -- Returns: bit
  3306. --          0 - The given character is not a white-space
  3307. --          1 - The given character is a white-space
  3308. -- 
  3309. -- Security: Execute permission of this function is granted to public
  3310. -- 
  3311. print 'Creating function fn_chariswhitespace'
  3312. print ''
  3313. go
  3314. create function system_function_schema.fn_chariswhitespace(
  3315.     @char nchar(1)
  3316.     ) returns bit
  3317. begin
  3318.     declare @result bit
  3319.  
  3320.     if @char in (N' ', nchar(9), nchar(10), nchar(13), N'')
  3321.     begin
  3322.         select @result = 1
  3323.     end
  3324.     else
  3325.     begin
  3326.         select @result = 0
  3327.     end
  3328.     return @result        
  3329. end
  3330. go
  3331.  
  3332. --
  3333. -- Name: fn_generateparameterpattern
  3334. --
  3335. -- Description: Given the name of a parameter (excluding the leading / or -), 
  3336. --              this function will return the pattern for matching the
  3337. --              parameter in a case-insensitive manner. For example
  3338. --  
  3339. --              select fn_generateparameterpattern(N'Ouptut')
  3340. -- 
  3341. --              will return
  3342. --
  3343. --              %[-/][Oo][Uu][Tt][Pp][Uu][Tt]%
  3344. --
  3345. -- Parameters: @parameter nvarchar(200)
  3346. --             
  3347. -- Notes: The leading / or - should be omitted from @parameter
  3348. --
  3349. -- Returns: nvarchar(806)
  3350. --
  3351. -- Security: Execute permission of this function is granted to public 
  3352. --
  3353. print 'Creating function fn_generateparameterpattern'
  3354. print ''
  3355. go
  3356. create function system_function_schema.fn_generateparameterpattern(
  3357.     @parameter nvarchar(200)
  3358.     ) returns nvarchar(806)
  3359. begin
  3360.     declare @pattern          nvarchar(806)
  3361.     declare @parameter_length int
  3362.     declare @i                int
  3363.     declare @c                nvarchar(1)
  3364.  
  3365.     select @pattern = N'%[-/]'
  3366.     select @i = 1
  3367.     select @parameter_length = len(@parameter)
  3368.     
  3369.     while @i <= @parameter_length
  3370.     begin
  3371.     select @c = substring(@parameter, @i, 1)        
  3372.     select @pattern = @pattern + N'[' + upper(@c collate SQL_Latin1_General_CP1_CS_AS) + lower(@c collate SQL_Latin1_General_CP1_CS_AS) + N']'
  3373.         select @i = @i + 1
  3374.     end 
  3375.     select @pattern = @pattern + '%'
  3376.     return @pattern
  3377. end
  3378. go
  3379.  
  3380. --
  3381. -- Name: fn_skipparameterargument
  3382. --
  3383. -- Description: This function basically removes the first non-parameter
  3384. --              token from the given command. It is designed to handle
  3385. --              square-bracket quoted or double-quoted parameter arguments.
  3386. --              Note that all white-spaces trailing the removed argument will 
  3387. --              also be removed in the returned command.
  3388. --
  3389. -- Parameters: @command nvarchar(3200)
  3390. -- 
  3391. -- Returns: nvarchar(3200)
  3392. --
  3393. -- Security: Execute permission of this function is granted to public
  3394. --              
  3395. print 'Creating function fn_skipparameterargument'
  3396. print ''
  3397. go
  3398. create function system_function_schema.fn_skipparameterargument(
  3399.     @command nvarchar(3200)
  3400.     ) returns nvarchar(3200)
  3401. begin
  3402.     declare @state int
  3403.     declare @i int
  3404.     declare @char nvarchar(1)
  3405.     declare @command_length int
  3406.     declare @state_start int
  3407.     declare @state_in_dquote_argument int
  3408.     declare @state_seen_matching_dquote int
  3409.     declare @state_in_square_bracket_argument int
  3410.     declare @state_seen_matching_bracket int
  3411.     declare @state_reached_end_of_argument int
  3412.     declare @state_in_unquoted_argument int
  3413.     declare @state_exit int
  3414.     -- Initializations
  3415.     select @state_start = 0
  3416.     select @state_in_dquote_argument = 1    
  3417.     select @state_seen_matching_dquote = 2
  3418.     select @state_in_square_bracket_argument = 3
  3419.     select @state_seen_matching_bracket = 4
  3420.     select @state_reached_end_of_argument = 5
  3421.     select @state_in_unquoted_argument = 6
  3422.     select @state_exit = 7
  3423.  
  3424.     select @i = 1
  3425.     select @state = @state_start
  3426.     select @command_length = len(@command)  
  3427.  
  3428.     while @i <= @command_length
  3429.     begin
  3430.  
  3431.         select @char = substring(@command,@i,1)
  3432.         select @state = 
  3433.             case @state 
  3434.             when @state_start then
  3435.                 case 
  3436.                 when fn_chariswhitespace(@char) = 1 then @state_start   
  3437.                 when @char in (N'-',N'/') then @state_exit
  3438.                 when @char in (N'[') then @state_in_square_bracket_argument
  3439.                 when @char in (N'"') then @state_in_dquote_argument
  3440.                 else @state_in_unquoted_argument
  3441.                 end
  3442.             when @state_in_dquote_argument then
  3443.                 case 
  3444.                 when @char in (N'"') then @state_seen_matching_dquote
  3445.                 else @state_in_dquote_argument
  3446.                 end
  3447.             when @state_seen_matching_dquote then
  3448.                 case 
  3449.                 when @char in (N'"') then @state_in_dquote_argument 
  3450.                 when fn_chariswhitespace(@char) = 1 then @state_reached_end_of_argument
  3451.                 else @state_exit
  3452.                 end
  3453.             when @state_in_square_bracket_argument then
  3454.                 case
  3455.                 when @char in (N']') then @state_seen_matching_bracket
  3456.                 else @state_in_square_bracket_argument  
  3457.                 end
  3458.             when @state_seen_matching_bracket then
  3459.                 case 
  3460.                 when @char in (N']') then @state_in_square_bracket_argument
  3461.                 when fn_chariswhitespace(@char) = 1 then @state_reached_end_of_argument
  3462.                 else @state_exit
  3463.                 end
  3464.             when @state_reached_end_of_argument then
  3465.                 case 
  3466.                 when fn_chariswhitespace(@char) = 1 then @state_reached_end_of_argument
  3467.                 else @state_exit    
  3468.                 end
  3469.             when @state_in_unquoted_argument then
  3470.                 case
  3471.                 when fn_chariswhitespace(@char) = 1 then @state_reached_end_of_argument
  3472.                 else @state_in_unquoted_argument
  3473.                 end
  3474.             else @state         
  3475.             end 
  3476.  
  3477.         if @state = @state_exit
  3478.         begin
  3479.             goto done
  3480.         end
  3481.     select @i = @i + 1
  3482.     end -- while
  3483. done:
  3484.     select @command = substring(@command, @i, @command_length - @i + 1)
  3485.     return @command 
  3486. end
  3487. go  
  3488.  
  3489. -- 
  3490. -- Name: fn_removeparameterwithargument
  3491. -- 
  3492. -- Description: This function removes all instances of a parameter and their
  3493. --              arguments from a given command line.
  3494. --
  3495. -- Notes: @parameter must be specified without the leading / or -
  3496. --
  3497. -- Parameters: @command nvarchar(3200)
  3498. --             @parameter nvarchar(200)
  3499. --
  3500. -- Returns: @nvarchar(3200)
  3501. -- 
  3502. -- Security: Execute permission of this function is granted to public
  3503. --
  3504. print 'Creating function fn_reomveparameterwithargument'
  3505. print ''
  3506. go
  3507. create function system_function_schema.fn_removeparameterwithargument(
  3508.     @command nvarchar(3200),
  3509.     @parameter nvarchar(200)
  3510.     ) returns nvarchar(3200)
  3511. begin
  3512.  
  3513.     declare @pattern nvarchar(806)
  3514.     declare @resulting_command nvarchar(3200)
  3515.     declare @command_length int
  3516.     declare @pattern_start int
  3517.     declare @first_iteration bit
  3518.     declare @parameter_length int
  3519.  
  3520.     select @first_iteration = 1
  3521.     select @pattern = fn_generateparameterpattern(@parameter)
  3522.     select @parameter_length = len(@parameter) + 1 -- leading - or /
  3523.     
  3524.     select @resulting_command = N''
  3525.     select @pattern_start = patindex(@pattern,@command) 
  3526.     while @pattern_start <> 0 and @pattern_start is not NULL
  3527.     begin
  3528.         select @command_length = len(@command)
  3529.  
  3530.         -- Check if the pattern found is properly delimited in the command.
  3531.         -- If so, try to skip over the next token. 
  3532.         if (@pattern_start = 1 and @first_iteration = 1 or
  3533.             (@pattern_start > 1 and fn_chariswhitespace(substring(@command, @pattern_start - 1, 1)) = 1))  and
  3534.             (fn_chariswhitespace(substring(@command, @pattern_start + @parameter_length, 1)) = 1)             
  3535.         begin
  3536.             -- Add everything before the parameter to the resulting command
  3537.             select @resulting_command = @resulting_command + rtrim(substring(@command, 1, @pattern_start - 1))
  3538.  
  3539.             -- Eat the parameter
  3540.             select @command = substring(@command, @pattern_start + @parameter_length, @command_length - @pattern_start - @parameter_length + 1)
  3541.  
  3542.             -- Skip over the argument of the parameter
  3543.             select @command = fn_skipparameterargument(@command)
  3544.  
  3545.             if @resulting_command <> N''
  3546.             begin
  3547.                 select @resulting_command = @resulting_command + N' '
  3548.             end
  3549.         end  
  3550.         else    
  3551.         begin
  3552.             -- Not a properly delimited parameter so transfer the 
  3553.             -- matching substring to the resulting command and
  3554.             -- eat the substring in the process
  3555.             select @resulting_command = @resulting_command + substring(@command, 1, @pattern_start + @parameter_length - 1)
  3556.             select @command = substring(@command, @pattern_start + @parameter_length, @command_length - @pattern_start - @parameter_length + 1)
  3557.         end
  3558.         select @first_iteration = 0
  3559.         select @pattern_start = patindex(@pattern, @command) 
  3560.     end 
  3561.     select @resulting_command = @resulting_command + @command
  3562.     return @resulting_command
  3563. end
  3564. go
  3565.  
  3566. --
  3567. -- Name: fn_updateparameterwithargument
  3568. --
  3569. -- Description: This function updates the argument value of the specified
  3570. --              parameter in the given command line. If there are multiple
  3571. --              instances of the specified parameter in the command line, 
  3572. --              only the first instance will be updated and all subsequent 
  3573. --              instances will be removed. If the command line does not 
  3574. --              contain the specified parameter in the first place, this
  3575. --              function will append the specified parameter and argument 
  3576. --              to the command line.
  3577. --
  3578. -- Notes: Any quoting that is required for the argument should be done
  3579. --        before calling this function.
  3580. --
  3581. -- Parameters: @command nvarchar(3200)
  3582. --             @parameter nvarchar(200)
  3583. --             @argument nvarchar(1000)
  3584. --            
  3585. -- Returns: nvarchar(3200)
  3586. --
  3587. -- Security: Execute permission of this function is granted to public
  3588. --
  3589. print 'Creating function fn_updateparameterwithargument'
  3590. print ''
  3591. go
  3592. create function system_function_schema.fn_updateparameterwithargument(
  3593.     @command nvarchar(3200),
  3594.     @parameter nvarchar(200),
  3595.     @argument  nvarchar(1000)
  3596.     ) returns nvarchar(3200)
  3597. begin
  3598.     declare @pattern nvarchar(806)
  3599.     declare @resulting_command nvarchar(3200)
  3600.     declare @command_length int
  3601.     declare @pattern_start int
  3602.     declare @first_iteration bit
  3603.     declare @parameter_length int
  3604.     declare @found_parameter bit
  3605.     
  3606.     select @first_iteration = 1
  3607.     select @found_parameter = 0
  3608.     select @pattern = fn_generateparameterpattern(@parameter)
  3609.     select @parameter_length = len(@parameter) + 1 -- leading - or /
  3610.  
  3611.     select @resulting_command = N''
  3612.     select @pattern_start = patindex(@pattern,@command)
  3613.         
  3614.     if @argument is null
  3615.     begin
  3616.         select @argument = N''
  3617.     end
  3618.  
  3619.     while @pattern_start <> 0 and @pattern_start is not null
  3620.     begin
  3621.         select @command_length = len(@command)
  3622.  
  3623.         -- Check if the pattern found is properly delimited in the command,
  3624.         -- If so, try to change the argument of the parameter with the given
  3625.         -- value.
  3626.         if (@pattern_start = 1 and @first_iteration = 1 or
  3627.             (@pattern_start > 1 and fn_chariswhitespace(substring(@command, @pattern_start - 1, 1)) = 1)) and
  3628.             (fn_chariswhitespace(substring(@command, @pattern_start + @parameter_length, 1)) = 1)
  3629.         begin
  3630.  
  3631.             -- Add everything before the parameter to the resulting command
  3632.             select @resulting_command = @resulting_command + rtrim(substring(@command, 1, @pattern_start - 1))
  3633.  
  3634.             -- Add back the parameter with the specified argument
  3635.             if @resulting_command <> ''
  3636.             begin
  3637.                 select @resulting_command = @resulting_command + N' '
  3638.             end
  3639.             select @resulting_command = @resulting_command + N'-' + @parameter + N' ' + rtrim(ltrim(@argument)) + ' '
  3640.  
  3641.             -- Remove the leading part of the command up to the begining of the
  3642.             -- matching pattern
  3643.             select @command = substring(@command, @pattern_start, @command_length - @pattern_start + 1)
  3644.  
  3645.             -- Remove all traces of the specified parameter from the remaining
  3646.             -- command line
  3647.             select @command = fn_removeparameterwithargument(@command, @parameter)
  3648.             select @found_parameter = 1
  3649.         end
  3650.         else
  3651.         begin
  3652.             -- Not a properly delimited parameter so transfer the 
  3653.             -- matching substring to the resulting command and
  3654.             -- eat the substring in the process
  3655.             select @resulting_command = @resulting_command + substring(@command, 1, @pattern_start + @parameter_length - 1)
  3656.             select @command = substring(@command, @pattern_start + @parameter_length, @command_length - @pattern_start - @parameter_length + 1)
  3657.         end
  3658.  
  3659.         select @first_iteration = 0
  3660.         select @pattern_start = patindex(@pattern, @command)
  3661.     end
  3662.  
  3663.     select @resulting_command = @resulting_command + @command
  3664.  
  3665.     if @found_parameter = 0
  3666.     begin
  3667.         select @resulting_command = rtrim(@resulting_command) + N' ' + N'-' +
  3668.                @parameter + N' ' + rtrim(ltrim(@argument)) 
  3669.     end
  3670.     return @resulting_command
  3671. end
  3672. go
  3673.  
  3674. --
  3675. -- Name: sp_MSreplcheckoffloadserver
  3676. --
  3677. -- Description: A simple procedure for checking whether a specified
  3678. --              offload server name contains invalid characters.
  3679. --
  3680. -- Parameter: @offloadserver sysname (mandatory)
  3681. --
  3682. -- Security: Admin only
  3683. --
  3684. -- Returns: 0 - The specified offload server name doesn't contain invalid 
  3685. --             characters
  3686. --         1 - The specified offload server name contains invalid characters
  3687. --
  3688. print ''
  3689. print 'Creating procedure sp_MSreplcheckoffloadserver'
  3690. go
  3691. create procedure sp_MSreplcheckoffloadserver (
  3692.     @offloadserver sysname
  3693.     )
  3694. as 
  3695. begin
  3696.     -- @offload_server being null is ok
  3697.     -- look for '\'
  3698.     if 0 < charindex('\', @offloadserver)
  3699.     begin
  3700.         raiserror(21368,-1,-1,N'\')
  3701.         return 1
  3702.     end
  3703.     return 0
  3704. end
  3705. go
  3706. exec sp_MS_marksystemobject sp_MSreplcheckoffloadserver
  3707. go
  3708.  
  3709. --
  3710. -- Name: fn_MSrepl_get_unique_name
  3711. --
  3712. -- Description: Use the prefixes passed in to generate a unique name based on a new GUID
  3713. -- which is less than 100 characters (100 is task name limit) as
  3714. -- 'prefix1-prefix2-prefix3-prefix4-hex_of_guid'
  3715. -- All prefixes are optional.
  3716. --
  3717. -- Security: To public
  3718. --
  3719. raiserror('Creating function fn_repluniquename', 0,1)
  3720. go
  3721.  
  3722. create function system_function_schema.fn_repluniquename (
  3723. -- cannot use newid() in a UDF
  3724.     @guid uniqueidentifier,
  3725.     @prefix1 sysname = NULL,
  3726.     @prefix2 sysname = NULL,
  3727.     @prefix3 sysname = NULL,
  3728.     @prefix4 sysname = NULL
  3729.     ) returns nvarchar(100)
  3730. as
  3731. begin
  3732.     declare @name nvarchar(100)
  3733.     select @name = N''
  3734.  
  3735.     -- Max len is (16 + 1) * 4 + 32 = 100
  3736.     if @prefix1 is not null
  3737.         select @name = @name + CONVERT(nvarchar(16),@prefix1) + N'-'
  3738.     if @prefix2 is not null
  3739.         select @name = @name + CONVERT(nvarchar(16),@prefix2) + N'-'
  3740.     if @prefix3 is not null
  3741.         select @name = @name + CONVERT(nvarchar(16),@prefix3) + N'-'
  3742.     if @prefix4 is not null
  3743.         select @name = @name + CONVERT(nvarchar(16),@prefix4) + N'-'
  3744.  
  3745.     select @name = @name + replace(convert(nvarchar(36), @guid), N'-',N'')
  3746.     return @name
  3747. end
  3748. go
  3749.  
  3750. print ''
  3751. print 'Creating procedure sp_MSget_file_existence'
  3752. go
  3753. create procedure sp_MSget_file_existence (
  3754. @filename nvarchar(260),
  3755. @exists bit = 0 output
  3756. )
  3757. AS
  3758.     SET NOCOUNT ON
  3759.  
  3760.     DECLARE @command nvarchar(512)
  3761.     DECLARE @retcode int
  3762.     declare @echo_text nvarchar(20)
  3763.  
  3764.     select @echo_text = 'file_exists'
  3765.  
  3766.     /*
  3767.     ** The return code from xp_cmdshell is not a reliable way to check whether the file exists or
  3768.     ** not. It is always 0 on Win95 as long as xp_cmdshell succeeds.
  3769.     */  
  3770.  
  3771.     select @command = N'if exist "' + fn_escapecmdshellsymbolsremovequotes(@filename) collate database_default + N'" echo ' + @echo_text
  3772.  
  3773.     create table #text_ret(cmdoutput nvarchar(20) collate database_default null)
  3774.  
  3775.     insert into #text_ret exec @retcode = master..xp_cmdshell @command
  3776.     if @@error <> 0 or @retcode <> 0
  3777.         return 1
  3778.  
  3779.     if exists (select * from #text_ret where ltrim(rtrim(cmdoutput)) = @echo_text)
  3780.         select @exists = 1
  3781.     else 
  3782.         select @exists = 0
  3783.  
  3784.     drop table #text_ret
  3785. go
  3786. EXEC dbo.sp_MS_marksystemobject sp_MSget_file_existence
  3787. GO
  3788.  
  3789.  
  3790. raiserror('Creating procedure sp_MSrepl_isdbowner', 0,1)
  3791. go
  3792. CREATE PROCEDURE sp_MSrepl_isdbowner 
  3793.     @dbname nvarchar(255)
  3794. AS
  3795. BEGIN
  3796.     SET NOCOUNT ON
  3797.     DECLARE @retcode int
  3798.     DECLARE @cmd      nvarchar(255)
  3799.     DECLARE @isdbowner int
  3800.  
  3801.     SELECT @retcode = has_dbaccess(@dbname)
  3802.     IF (@retcode IS NULL) OR (@retcode = 0)
  3803.     BEGIN
  3804.         /* 
  3805.         ** Either no access or database not found 
  3806.         ** No need to go further
  3807.         */
  3808.         RETURN 0
  3809.     END
  3810.  
  3811.     SELECT @cmd = 'USE ' + quotename(@dbname) + ' SELECT @isdbowner = is_member(''db_owner'')'
  3812.     EXEC sp_executesql @cmd, N'@isdbowner int output', @isdbowner output
  3813.  
  3814.     RETURN isnull(@isdbowner, 0)
  3815. END
  3816. GO
  3817.  
  3818. raiserror('Creating procedure sp_resyncmergesubscription', 0,1)
  3819. go
  3820. CREATE PROCEDURE sp_resyncmergesubscription 
  3821.     @publisher            sysname = NULL,
  3822.     @publisher_db        sysname = NULL,
  3823.     @publication        sysname,
  3824.     @subscriber            sysname = NULL,
  3825.     @subscriber_db        sysname = NULL,
  3826.     @resync_type        int, --0:force convergence, 1: since last successful validation, 2:since a given date
  3827.     @resync_date_str    nvarchar(30) = NULL
  3828. AS
  3829.     declare @retcode             int
  3830.     declare @subid                uniqueidentifier
  3831.     declare @pubid                uniqueidentifier
  3832.     declare @subscriber_srvid     int
  3833.     declare @resync_gen            int
  3834.     declare @resync_date        datetime
  3835.     /*
  3836.     ** Security Check
  3837.     */
  3838.  
  3839.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  3840.     IF @@ERROR <> 0 or @retcode <> 0
  3841.         return (1)
  3842.  
  3843.     if isdate(@resync_date_str)=0 and @resync_type=2
  3844.     begin
  3845.         raiserror(21370, 16, -1, @resync_date_str)
  3846.         return (1)
  3847.     end
  3848.     if @resync_date_str is not NULL
  3849.         select @resync_date=convert(datetime, @resync_date_str)
  3850.     else
  3851.         select @resync_date = NULl
  3852.     
  3853.     /*
  3854.     ** parameter checking for null/not-null; including validity of @resync_type and @resync_date
  3855.     */
  3856.  
  3857.     if ((@publisher is NULL and @subscriber is NULL) or
  3858.        (@publisher is not NULL and @subscriber is not NULL) or
  3859.        (@publisher is NULL and @publisher_db is not NULL) or
  3860.        (@subscriber is NULL and @subscriber_db is not NULL) or
  3861.        (@publisher is not NULL and @publisher_db is NULL) or
  3862.        (@subscriber is not NULL and @subscriber_db is NULL))
  3863.        begin
  3864.                raiserror(21294, 16, -1)
  3865.                return (1)
  3866.        end
  3867.  
  3868.     if @resync_type<0 or @resync_type>2
  3869.         begin
  3870.             raiserror(21296, 16, -1)
  3871.             return (1)
  3872.         end
  3873.  
  3874.     if @publisher is NULL    
  3875.         select @publisher=@@SERVERNAME
  3876.     if @publisher_db is NULL
  3877.         select @publisher_db=db_name()
  3878.     if @subscriber is NULL
  3879.         select @subscriber=@@SERVERNAME
  3880.     if @subscriber_db is NULL
  3881.         select @subscriber_db=db_name()
  3882.         
  3883.     select @pubid = pubid from sysmergepublications where name=@publication and lower(publisher)=lower(@publisher) and publisher_db=@publisher_db
  3884.     if (@pubid is null)
  3885.         begin
  3886.             RAISERROR (20026, 16, -1, @publication)
  3887.             return (1)
  3888.         end
  3889.     select @subscriber_srvid=srvid from master..sysservers where LOWER(srvname)=LOWER(@subscriber) collate database_default
  3890.     select @subid=subid from sysmergesubscriptions where pubid=@pubid and srvid=@subscriber_srvid and db_name=@subscriber_db
  3891.     if @resync_type > 0 --since a given date or last validation    
  3892.         begin
  3893.             if @resync_type = 1    -- last validation time; make sure resync_date is not NULL in this case; 
  3894.                 begin
  3895.                     select @resync_date=last_validated from sysmergesubscriptions where subid=@subid
  3896.                     -- invalid case - there is no prior validation, this call is a non-op.
  3897.                     if @resync_date is NULL
  3898.                         begin
  3899.                             raiserror(21370, 16, -1)
  3900.                             return (1)
  3901.                         end
  3902.                 end
  3903.                 
  3904.             declare @guidnull uniqueidentifier
  3905.             set @guidnull= '00000000-0000-0000-0000-000000000000'
  3906.             
  3907.             exec sp_MSlocalizeinterruptedgenerations
  3908.             select @resync_gen=NULL
  3909.             select top 1 @resync_gen=generation from MSmerge_genhistory 
  3910.                 where     coldate > @resync_date 
  3911.                         and art_nick in (select nickname from sysmergearticles where pubid=@pubid)
  3912.                         and guidlocal <> @guidnull
  3913.                     order by coldate ASC
  3914.             -- this is valid case, meaning there is no need to do any resynchronization
  3915.             if @resync_gen is NULL
  3916.                 begin
  3917.                     return (0)
  3918.                 end
  3919.         end
  3920.     else if @resync_type=0
  3921.         select @resync_gen=0 -- force convergence case
  3922.     update  sysmergesubscriptions  set resync_gen=@resync_gen where subid=@subid
  3923.     if @@ERROR<>0
  3924.         begin
  3925.             raiserror(21298, 16, -1)
  3926.             return (1)
  3927.         end
  3928. Go
  3929. EXEC dbo.sp_MS_marksystemobject sp_resyncmergesubscription
  3930. GO
  3931. grant exec on sp_resyncmergesubscription to public
  3932. go
  3933.  
  3934.  
  3935.  
  3936. raiserror('Creating procedure sp_MSget_qualified_name', 0,1)
  3937. GO
  3938. CREATE PROCEDURE sp_MSget_qualified_name (
  3939.     @object_id                int,                         
  3940.     @qualified_name            nvarchar(512)    output       
  3941. )AS
  3942.     if object_name(@object_id) is not null
  3943.         select @qualified_name = quotename(user_name(OBJECTPROPERTY(@object_id,'OwnerId'))) collate database_default + 
  3944.             N'.' + quotename(object_name(@object_id)) collate database_default
  3945.     else
  3946.         select @qualified_name = NULL
  3947. GO
  3948. exec dbo.sp_MS_marksystemobject sp_MSget_qualified_name
  3949. go
  3950.  
  3951.  
  3952. raiserror('Creating procedure sp_MSdrop_object', 0,1)
  3953. GO
  3954.  
  3955. CREATE PROCEDURE sp_MSdrop_object (
  3956.         @object_id int = NULL,
  3957.         @object_name sysname = NULL,
  3958.         @object_owner sysname = NULL
  3959.         )
  3960.     AS
  3961.  
  3962.     SET NOCOUNT ON
  3963.  
  3964.     declare @cmd nvarchar(1000)
  3965.     
  3966.     if @object_name is not null
  3967.     begin
  3968.         declare @owner_id int
  3969.         if @object_owner is null
  3970.             select @owner_id = user_id()
  3971.         else
  3972.             select @owner_id = user_id(@object_owner)
  3973.         select @object_id = id from sysobjects where
  3974.             name = @object_name and
  3975.             uid = @owner_id
  3976.        end
  3977.  
  3978.        if @object_id is not null
  3979.        begin
  3980.            exec dbo.sp_MSget_qualified_name @object_id, @cmd output
  3981.            if objectproperty(@object_id, 'IsTable') = 1
  3982.                select @cmd = 'drop table ' + @cmd
  3983.            else if objectproperty(@object_id, 'IsProcedure') = 1
  3984.                select @cmd = 'drop procedure ' + @cmd
  3985.            else if objectproperty(@object_id, 'IsTrigger') = 1
  3986.                select @cmd = 'drop trigger ' + @cmd
  3987.            else if objectproperty(@object_id, 'IsView') = 1
  3988.                select @cmd = 'drop view ' + @cmd
  3989.        end
  3990.  
  3991.        exec (@cmd)
  3992.        if @@error <> 0
  3993.            return(1)
  3994.  
  3995. GO
  3996.  
  3997. print ''
  3998. print 'Creating procedure sp_isarticlecolbitset'
  3999. go
  4000.  
  4001. create procedure sp_isarticlecolbitset @colid int, @colbitmap binary(32)
  4002. as
  4003. declare @word tinyint
  4004. declare @mval int
  4005. declare @mask  smallint
  4006.  
  4007. select @word = convert(tinyint, 16 - floor((@colid-1)/16))
  4008. select @mval = power(2, (@colid-1) % 16 )
  4009. select @mask = convert( smallint, convert( binary(2), substring( convert( nchar(2), convert( binary(4), @mval ) ), 2, 1 ) ) )
  4010.  
  4011.  
  4012. if convert( binary(2), substring( convert( nchar(16),@colbitmap), @word, 1 ) ) & @mask = @mask 
  4013. begin   
  4014.    return 1
  4015. end
  4016. else
  4017. begin
  4018.    return 0
  4019. end
  4020.  
  4021. go
  4022.  
  4023. EXEC dbo.sp_MS_marksystemobject sp_isarticlecolbitset
  4024. GO
  4025.  
  4026. print ''
  4027. print 'Creating procedure sp_getarticlepkcolbitmap'
  4028. go
  4029.  
  4030. create procedure sp_getarticlepkcolbitmap @tabid int, @colbitmap binary(32) output
  4031. as
  4032. declare @pkindid int
  4033. declare @indkey int
  4034. declare @colid int
  4035. declare @word tinyint
  4036. declare @mval    int
  4037. declare @mask    binary(2)
  4038. declare @wordval binary(2)
  4039. declare @objname nvarchar(265)
  4040.  
  4041. select @colbitmap = 0x00
  4042.  
  4043. if exists( select * from sysobjects where id = @tabid and xtype = 'V' )
  4044. begin
  4045.     select @pkindid = 1
  4046. end
  4047. else
  4048. begin
  4049.     select @pkindid = indid from sysindexes where id = @tabid and status & 2048 <> 0
  4050. end
  4051.  
  4052. select @indkey = 1
  4053. select @objname = QUOTENAME(user_name(OBJECTPROPERTY(@tabid, 'OwnerId'))) collate database_default + N'.' collate database_default + QUOTENAME(object_name( @tabid )) collate database_default 
  4054.  
  4055. while @indkey <= 16 and index_col( @objname, @pkindid, @indkey ) is not null
  4056. begin
  4057.     select @colid = colid from syscolumns where id = @tabid 
  4058.            and name = index_col( @objname, @pkindid, @indkey )
  4059.     select @word = convert(tinyint, 16 - floor((@colid-1)/16))
  4060.  
  4061.     select @mval = power(2, (@colid-1) % 16 )
  4062.     select @mask = convert( binary(2), substring( convert( nchar(2), convert( binary(4), @mval ) ), 2, 1 ) )                                 
  4063.  
  4064.     select @wordval = convert( binary(2), substring( convert( nchar(16), @colbitmap ), @word, 1 ) )
  4065.     select @wordval = convert( binary(2), convert( smallint, @wordval) | convert( smallint, @mask) )
  4066.  
  4067.     select @colbitmap = convert(binary(32), STUFF( convert(nchar(16),@colbitmap), @word, 1, convert( nchar(1),@wordval))) 
  4068.       
  4069.     select @indkey = @indkey + 1
  4070. end
  4071. go
  4072.  
  4073. EXEC dbo.sp_MS_marksystemobject sp_getarticlepkcolbitmap
  4074. GO
  4075.  
  4076. raiserror('Creating procedure sp_MSsubst_filter_name', 0,1)
  4077. GO
  4078. create procedure sp_MSsubst_filter_name 
  4079. @srch_string nvarchar(500), 
  4080. @rplc_string nvarchar(500), 
  4081. @filter_clause nvarchar(4000) output
  4082. as
  4083.  
  4084. declare @expansion int  -- BYTES data will be expanded/contracted by
  4085. declare @subst_offset int -- CHARACTER OFFSET at which to perform string operations
  4086.  
  4087. select @expansion = datalength(@rplc_string) - datalength(@srch_string) 
  4088. select @subst_offset = 0
  4089.  
  4090. -- Note!  procedure is case insensitive
  4091.  
  4092. select @subst_offset = charindex( upper(@srch_string), upper(@filter_clause), @subst_offset )
  4093. while( @subst_offset <> 0 )
  4094. begin
  4095.     if datalength( @filter_clause ) + @expansion > 8000
  4096.     begin
  4097.         -- buffer overflow, return error
  4098.         return 1
  4099.     end
  4100.     else
  4101.     begin
  4102.         select @filter_clause = stuff( @filter_clause, @subst_offset, datalength( @srch_string ) / 2, @rplc_string )
  4103.         select @subst_offset = @subst_offset + @expansion / 2
  4104.     end
  4105.     select @subst_offset = charindex( upper(@srch_string), upper(@filter_clause), @subst_offset )
  4106. end
  4107. return 0
  4108. go
  4109.  
  4110. raiserror('Creating procedure sp_MSsubst_filter_names', 0,1)
  4111. GO
  4112.  
  4113. create procedure sp_MSsubst_filter_names 
  4114. @owner sysname, 
  4115. @table sysname, 
  4116. @filter_clause nvarchar(4000) output
  4117. as
  4118. declare @retcode int
  4119. declare @rplc_string nvarchar( 513 )
  4120.  
  4121. if @filter_clause is null or @table is null
  4122. begin 
  4123.     -- error, @filter_clause cannot be null
  4124.     return 1
  4125. end
  4126.  
  4127. if @owner is not null
  4128. begin
  4129.     select @rplc_string = QUOTENAME(@owner) + N'.'
  4130. end
  4131. else
  4132. begin
  4133.     select @rplc_string = N''
  4134. end
  4135.  
  4136. select @rplc_string = @rplc_string + QUOTENAME(@table)
  4137.  
  4138. exec @retcode = sp_MSsubst_filter_name N'<<TABLE>>', @rplc_string, @filter_clause output 
  4139. if @retcode <> 0 or @@error <> 0
  4140. begin
  4141.     return 1
  4142. end
  4143.  
  4144. return 0
  4145.  
  4146. raiserror('Creating procedure sp_MSreplcheck_name', 0,1)
  4147. GO
  4148.  
  4149. CREATE PROCEDURE sp_MSreplcheck_name
  4150.     @name            sysname,
  4151.     @raise_error    bit = 1
  4152. AS
  4153.     declare @index    int
  4154.  
  4155.     Set nocount on
  4156.  
  4157.     -- Name cannot be NULL or empty ("")
  4158.     -- Blank identifiers (" ") are allowed
  4159.     IF (@name is null OR datalength(@name) = 0)
  4160.     begin
  4161.         if @raise_error = 1
  4162.             raiserror (15004,16,-1)
  4163.         return (1)
  4164.     end
  4165.  
  4166.     -- Check for proscribed characters
  4167.  
  4168.     declare @length int
  4169.     select @length = datalength( @name ) / 2
  4170.     select @index = 1
  4171.     while @index < @length
  4172.     begin
  4173.         if( 0 = unicode( substring( @name, @index, 1 ) ) )
  4174.         begin
  4175.             if @raise_error = 1
  4176.                 raiserror(15006,16,-1,@name)
  4177.             return (1)
  4178.         end
  4179.  
  4180.         select @index = @index + 1
  4181.     end
  4182.  
  4183.     --check for other proscribed characters
  4184.  
  4185.     select @index = charindex( N'%', @name)
  4186.     if (@index <> 0)
  4187.     begin
  4188.         if @raise_error = 1
  4189.             raiserror(15006,16,-1,@name)
  4190.         return (1)
  4191.     end
  4192.     select @index = charindex(N'*', @name)
  4193.     if (@index <> 0)
  4194.     begin
  4195.         if @raise_error = 1
  4196.             raiserror(15006,16,-1,@name)
  4197.         return (1)
  4198.     end
  4199.     select @index = charindex(N'[', @name)
  4200.     if (@index <> 0)
  4201.     begin
  4202.         if @raise_error = 1
  4203.             raiserror(15006,16,-1,@name)
  4204.         return (1)
  4205.     end
  4206.     select @index = charindex(N']', @name)
  4207.     if (@index <> 0)
  4208.     begin
  4209.         if @raise_error = 1
  4210.             raiserror(15006,16,-1,@name)
  4211.         return (1)
  4212.     end
  4213.     select @index = charindex(N'|', @name)
  4214.     if (@index <> 0)
  4215.     begin
  4216.         if @raise_error = 1
  4217.             raiserror(15006,16,-1,@name)
  4218.         return (1)
  4219.     end
  4220.     select @index = charindex(N':', @name)
  4221.     if (@index <> 0)
  4222.     begin
  4223.         if @raise_error = 1
  4224.             raiserror(15006,16,-1,@name)
  4225.         return (1)
  4226.     end
  4227.     select @index = charindex(N'"', @name)
  4228.     if (@index <> 0)
  4229.     begin
  4230.         if @raise_error = 1
  4231.             raiserror(15006,16,-1,@name)
  4232.         return (1)
  4233.     end
  4234.     select @index = charindex(N'?', @name)
  4235.     if (@index <> 0)
  4236.     begin
  4237.         if @raise_error = 1
  4238.             raiserror(15006,16,-1,@name)
  4239.         return (1)
  4240.     end
  4241.     /*
  4242.     ** Fix 52855 - allow single quote
  4243.     **
  4244.     select @index = charindex(N'''', @name)
  4245.     if (@index <> 0)
  4246.     begin
  4247.         if @raise_error = 1
  4248.             raiserror(15006,16,-1,@name)
  4249.         return (1)
  4250.     end
  4251.     */
  4252.     select @index = charindex(N'\', @name)
  4253.     if (@index <> 0)
  4254.     begin
  4255.         if @raise_error = 1
  4256.             raiserror(15006,16,-1,@name)
  4257.         return (1)
  4258.     end
  4259.     select @index = charindex(N'/', @name)
  4260.     if (@index <> 0)
  4261.     begin
  4262.         if @raise_error = 1
  4263.             raiserror(15006,16,-1,@name)
  4264.         return (1)
  4265.     end
  4266.     select @index = charindex(N'<', @name)
  4267.     if (@index <> 0)
  4268.     begin
  4269.         if @raise_error = 1
  4270.             raiserror(15006,16,-1,@name)
  4271.         return (1)
  4272.     end
  4273.     select @index = charindex(N'>', @name)
  4274.     if (@index <> 0)
  4275.     begin
  4276.         if @raise_error = 1
  4277.             raiserror(15006,16,-1,@name)
  4278.         return (1)
  4279.     end
  4280.     
  4281.     -- return success
  4282.  
  4283.     return (0) 
  4284. GO
  4285.     
  4286.  
  4287. exec dbo.sp_MS_marksystemobject sp_MSreplcheck_name
  4288. go
  4289.  
  4290.  
  4291.  
  4292. raiserror('Creating procedure sp_MScheckvalidsystables', 0,1)
  4293. GO
  4294.  
  4295. create procedure sp_MScheckvalidsystables  @validsubs int output
  4296. AS
  4297.     if not exists (select name from sysobjects where name='sysmergesubscriptions')
  4298.         begin
  4299.         set @validsubs = 0
  4300.         return
  4301.         end
  4302.  
  4303.     /* Is there a valid non-loopback subscription? */
  4304.     if exists (select * from sysmergesubscriptions
  4305.         where db_name=db_name() and srvid = (select srvid from master..sysservers where UPPER(srvname) = UPPER(@@servername) collate database_default)
  4306.         and subid <> partnerid)
  4307.         begin
  4308.         set @validsubs = 1
  4309.         return
  4310.         end
  4311.     /* Only possible subscriptions are loopbacks.  If database not enabled for publishing,
  4312.     ** then they don't indicate a valid publication/subscription. */
  4313.     if not exists (select name from master..sysdatabases where
  4314.         (category & 4) = 4 and name = db_name() collate database_default)
  4315.         begin
  4316.         set @validsubs = 0
  4317.         return
  4318.         end
  4319.     /* Database has merge publishing turned on, is probably a publisher.  Look for loopback
  4320.     ** subscription just to be sure... */
  4321.     if exists (select * from sysmergesubscriptions
  4322.         where db_name=db_name() and srvid = (select srvid from master..sysservers where UPPER(srvname) = UPPER(@@servername) collate database_default))
  4323.         begin
  4324.         set @validsubs = 1
  4325.         return
  4326.         end
  4327.         
  4328.     /* Must not be valid... */    
  4329.     set @validsubs = 0
  4330.     return
  4331.  
  4332.  
  4333. GO
  4334.  
  4335.  
  4336. raiserror('Creating procedure sp_MSdrop_mergesystables', 0,1)
  4337. GO
  4338. create procedure sp_MSdrop_mergesystables as
  4339.  
  4340.     begin tran
  4341.     save transaction drop_mergesystables
  4342.     if exists (select * from sysobjects
  4343.         where name = 'sysmergearticles')
  4344.         begin
  4345.         drop table sysmergearticles
  4346.         end
  4347.     if @@error<>0
  4348.         goto Error
  4349.  
  4350.     if exists (select * from sysobjects
  4351.         where name = 'sysmergepublications')
  4352.         begin
  4353.         drop table sysmergepublications
  4354.         end
  4355.     if @@error<>0
  4356.         goto Error
  4357.  
  4358.     if exists (select * from sysobjects
  4359.         where name = 'sysmergesubscriptions')
  4360.         begin
  4361.         drop table sysmergesubscriptions
  4362.         end
  4363.     if @@error<>0
  4364.         goto Error
  4365.         
  4366.     if exists (select * from sysobjects
  4367.         where name = 'MSmerge_contents')
  4368.         begin
  4369.         drop table MSmerge_contents
  4370.         end
  4371.     if @@error<>0
  4372.         goto Error
  4373.  
  4374.     if exists (select * from sysobjects
  4375.         where name = 'MSmerge_replinfo')
  4376.         begin
  4377.         drop table MSmerge_replinfo
  4378.         end
  4379.     if @@error<>0
  4380.         goto Error
  4381.         
  4382.     if exists (select * from sysobjects
  4383.         where name = 'MSmerge_identity_range ')
  4384.         begin
  4385.         drop table MSmerge_identity_range 
  4386.         end
  4387.     if @@error<>0
  4388.         goto Error
  4389.  
  4390.  
  4391.     if exists (select * from sysobjects
  4392.         where name = 'MSmerge_tombstone')
  4393.         begin
  4394.         drop table MSmerge_tombstone
  4395.         end
  4396.     if @@error<>0
  4397.         goto Error
  4398.         
  4399.     if exists (select * from sysobjects
  4400.         where name = 'MSmerge_genhistory')
  4401.         begin
  4402.         drop table MSmerge_genhistory
  4403.         end
  4404.     if @@error<>0
  4405.         goto Error
  4406.         
  4407.     if exists (select * from sysobjects
  4408.         where name = 'MSmerge_delete_conflicts')
  4409.         begin
  4410.         drop table MSmerge_delete_conflicts
  4411.         end
  4412.     if @@error<>0
  4413.         goto Error
  4414.  
  4415.     if exists (select * from sysobjects
  4416.         where name = 'sysmergeschemachange')
  4417.         begin
  4418.         drop table sysmergeschemachange
  4419.         end
  4420.     if @@error<>0
  4421.         goto Error
  4422.  
  4423.     if exists (select * from sysobjects
  4424.         where name = 'sysmergesubsetfilters')
  4425.         begin
  4426.         drop table sysmergesubsetfilters
  4427.         end
  4428.     if @@error<>0
  4429.         goto Error
  4430.  
  4431.     if exists (select * from sysobjects
  4432.         where name = 'sysmergeschemaarticles')
  4433.         begin
  4434.         drop table sysmergeschemaarticles
  4435.         end
  4436.     if @@error<>0
  4437.         goto Error
  4438.         
  4439.     if exists (select * from sysobjects
  4440.         where name = 'MSmerge_errorlineage')
  4441.         begin
  4442.         drop table MSmerge_errorlineage
  4443.         end
  4444.     if @@error<>0
  4445.         goto Error
  4446.  
  4447.     if exists (select * from sysobjects
  4448.         where name = 'MSrepl_identity_range')
  4449.         begin
  4450.         drop table MSrepl_identity_range
  4451.         end
  4452.     if @@error<>0
  4453.         goto Error
  4454.     
  4455.     if exists (select * from sysobjects 
  4456.         where name = 'sysmergeextendedarticlesview')
  4457.         begin
  4458.         drop view sysmergeextendedarticlesview
  4459.         end
  4460.     if @@error<>0
  4461.         goto Error    
  4462.  
  4463.     if exists (select * from sysobjects
  4464.         where name = 'MSdynamicsnapshotjobs')
  4465.         begin
  4466.         drop table MSdynamicsnapshotjobs
  4467.         end
  4468.     if @@error<>0
  4469.         goto Error
  4470.  
  4471.     if exists (select * from sysobjects
  4472.         where name = 'MSmerge_altsyncpartners')
  4473.         begin
  4474.         drop table MSmerge_altsyncpartners
  4475.         end
  4476.     if @@error<>0
  4477.         goto Error
  4478.         
  4479.     if exists (select * from sysobjects
  4480.         where name = 'MSdynamicsnapshotviews')
  4481.         begin
  4482.         drop table MSdynamicsnapshotviews
  4483.         end
  4484.     if @@error<>0
  4485.         goto Error
  4486.  
  4487.     if exists (select * from master..sysobjects where type='P' and name='sp_MSremovedebuginfrastructure')
  4488.     begin
  4489.         declare @retval int
  4490.         exec @retval= dbo.sp_MSremovedebuginfrastructure
  4491.         if @@ERROR <> 0 or @retval <> 0 goto Error
  4492.     end
  4493.     
  4494.     commit transaction    
  4495.     return 0
  4496. Error:
  4497.     RAISERROR (20007, 16, -1)
  4498.     if @@trancount > 0
  4499.     begin
  4500.         ROLLBACK TRANSACTION drop_mergesystables
  4501.         COMMIT TRANSACTION
  4502.     end
  4503.     return 1
  4504. go
  4505.  
  4506. exec dbo.sp_MS_marksystemobject sp_MSdrop_mergesystables
  4507. go
  4508.  
  4509. raiserror ('Executing procedure dbo.sp_MSdrop_mergesystables.',0,1)
  4510. go
  4511. exec dbo.sp_MSdrop_mergesystables
  4512. go
  4513.  
  4514. dump tran master with no_log
  4515. go
  4516.  
  4517. raiserror('Creating procedure sp_MScreate_mergesystables',0,1)
  4518. GO
  4519. create procedure sp_MScreate_mergesystables as
  4520.  
  4521.     /* This is to make sure that the varbinary columns do not get padded */
  4522.  
  4523.     set ANSI_PADDING off
  4524.  
  4525.     DECLARE @exist bit 
  4526.     DECLARE @validsubs  int
  4527.     select @exist = 1
  4528.     
  4529.     begin tran
  4530.     save transaction MScreate_mergesystables
  4531.  
  4532.     exec dbo.sp_MScheckvalidsystables  @validsubs  output
  4533.     if @validsubs = 0
  4534.         exec dbo.sp_MSdrop_mergesystables
  4535.         
  4536.     if not exists (select * from sysobjects where name = 'sysmergepublications')
  4537.         begin
  4538.  
  4539.             raiserror('Creating table sysmergepublications',0,1)
  4540.             
  4541.             create table dbo.sysmergepublications
  4542.             (    publisher                sysname NOT NULL default @@servername,
  4543.                 publisher_db            sysname NOT NULL default db_name(),
  4544.                 name                    sysname                NOT NULL,
  4545.                 description                nvarchar(255)         NULL,
  4546.                 retention                int                    NULL,
  4547.                 publication_type         tinyint                NULL,
  4548.                 pubid                     uniqueidentifier     NOT NULL,
  4549.                 designmasterid            uniqueidentifier     NULL,
  4550.                 parentid                uniqueidentifier     NULL,
  4551.                 sync_mode                tinyint                NULL,
  4552.                 allow_push                int                    NULL,
  4553.                 allow_pull                int                    NULL,
  4554.                 allow_anonymous            int                    NULL,
  4555.                 centralized_conflicts    int                    NULL,
  4556.                 status                    tinyint                NULL,
  4557.                 snapshot_ready            tinyint                NULL,
  4558.                 enabled_for_internet    bit                    NOT NULL default 0,
  4559.                 dynamic_filters            bit                    NOT NULL default 0,
  4560.                 -- portable snapshot support
  4561.                 snapshot_in_defaultfolder   bit             NOT NULL default 1,
  4562.                 alt_snapshot_folder         nvarchar(255)   NULL,
  4563.                 -- Pre/post - snapshot commands
  4564.                 pre_snapshot_script         nvarchar(255)   NULL,
  4565.                 post_snapshot_script        nvarchar(255)   NULL,
  4566.                 -- Snapshot compression
  4567.                 compress_snapshot           bit             NOT NULL default 0,
  4568.                 -- Post 7.0 Ftp support
  4569.                 ftp_address                 sysname         NULL,
  4570.                 ftp_port                    int             NOT NULL default 21,
  4571.                 ftp_subdirectory            nvarchar(255)   NULL,
  4572.                 ftp_login                   sysname         NULL default N'anonymous',
  4573.                 ftp_password                nvarchar(524)   NULL,
  4574.                 conflict_retention            int                NULL,
  4575.                 keep_before_values            int                NULL default 0,
  4576.                 allow_subscription_copy        bit             NULL default 0,     
  4577.                 allow_synctoalternate        bit             NULL default 0,
  4578.                 validate_subscriber_info    nvarchar(500)    NULL,
  4579.                 ad_guidname                    sysname            NULL,
  4580.                 backward_comp_level            int                not NULL default 10, --7.0 RTM
  4581.                 max_concurrent_merge        int                not NULL default 0,
  4582.                 max_concurrent_dynamic_snapshots int        not NULL default 0
  4583.             )
  4584.             if @@ERROR <> 0
  4585.                 goto Error
  4586.             
  4587.             CREATE UNIQUE NONCLUSTERED INDEX nc1sysmergepublications 
  4588.                 ON sysmergepublications(pubid)
  4589.             if @@ERROR <> 0
  4590.                 goto Error
  4591.  
  4592.             exec dbo.sp_MS_marksystemobject sysmergepublications
  4593.             if @@ERROR <> 0
  4594.                 goto Error
  4595.             -- grant select on sysmergepublications to public
  4596.         end
  4597.  
  4598.     if not exists (select * from sysobjects where name = 'MSmerge_errorlineage')
  4599.         begin        
  4600.             raiserror('Creating table MSmerge_errorlineage',0,1)
  4601.             
  4602.             create table dbo.MSmerge_errorlineage (
  4603.             tablenick        int NOT NULL,
  4604.             rowguid            uniqueidentifier NOT NULL,
  4605.             lineage            varbinary(255)
  4606.             )
  4607.             exec dbo.sp_MS_marksystemobject MSmerge_errorlineage
  4608.             if @@ERROR <> 0
  4609.                 goto Error
  4610.             create unique clustered index uc1errorlineage on MSmerge_errorlineage(tablenick, rowguid)
  4611.             if @@ERROR <> 0
  4612.                 goto Error
  4613.             
  4614.             --grant select on MSmerge_errorlineage to public
  4615.         end
  4616.  
  4617.     -- this table exists at distribution/db and subscriber databse both
  4618.     if not exists (select * from sysobjects where name = 'MSrepl_identity_range')
  4619.         begin        
  4620.             raiserror('Creating table MSrepl_identity_range',0,1)
  4621.             
  4622.             create table dbo.MSrepl_identity_range (
  4623.             objid                    int not NULL primary key,
  4624.             next_seed                bigint NULL, --resource control
  4625.             pub_range                bigint NULL, --publisher range
  4626.             range                    bigint NULL, -- set by sp_addmergearticle
  4627.             max_identity            bigint NULL, --resource control
  4628.             threshold                int    NULL,    --in percentage, set by sp_addmergearticle
  4629.             current_max                bigint NULL    --max value for current check constraint,set by sp_addmergearticle
  4630.             )
  4631.             exec dbo.sp_MS_marksystemobject MSrepl_identity_range
  4632.             if @@ERROR <> 0
  4633.                 goto Error
  4634.  
  4635.             --grant select on MSrepl_identity_range to public
  4636.         end
  4637.  
  4638.     if not exists (select * from sysobjects where name = 'sysmergearticles')
  4639.         begin
  4640.         
  4641.             raiserror('Creating table sysmergearticles',0,1)
  4642.  
  4643.             
  4644.             create table dbo.sysmergearticles (
  4645.                 name                    sysname                NOT NULL,
  4646.                 type                    tinyint                NULL,
  4647.                 objid                    int                    NOT NULL, 
  4648.                 sync_objid                int                    NOT NULL,
  4649.                 view_type                 tinyint                NULL,
  4650.                 artid                    uniqueidentifier    NOT NULL,
  4651.                 description                nvarchar(255)        NULL,
  4652.                 pre_creation_command    tinyint                NULL,
  4653.                 pubid                    uniqueidentifier     NOT NULL,
  4654.                 nickname                int                    NOT NULL,
  4655.                 column_tracking            int                    NOT NULL,
  4656.                 status                    tinyint                NULL,
  4657.                 conflict_table            sysname                NULL,
  4658.                 creation_script            nvarchar(255)        NULL,
  4659.                 conflict_script            nvarchar(255)        NULL,
  4660.                 article_resolver        nvarchar(255)        NULL,
  4661.                 ins_conflict_proc        sysname                NULL,
  4662.                 insert_proc                sysname                NULL,
  4663.                 update_proc                sysname                NULL,
  4664.                 select_proc                sysname                NULL,
  4665.                 schema_option             binary(8)             NULL,
  4666.                 destination_object        sysname                NOT NULL,
  4667.                 destination_owner        sysname                NULL,
  4668.                 resolver_clsid            nvarchar(50)        NULL,
  4669.                 subset_filterclause        nvarchar(1000)      NULL,
  4670.                 missing_col_count        int                    NULL,
  4671.                 missing_cols            varbinary(128)        NULL,
  4672.                 excluded_cols            varbinary(128)        NULL,
  4673.                 excluded_col_count        int                    not NULL default 0,
  4674.                 columns                    varbinary(128)       NULL,
  4675.                 resolver_info            nvarchar(255)        NULL,
  4676.                 view_sel_proc            nvarchar(290)        NULL,
  4677.                 gen_cur                    int                    NULL,
  4678.                 vertical_partition        int                    not NULL default 0,
  4679.                 identity_support        int                    not NULL default 0,
  4680.                 before_image_objid        int                    NULL,
  4681.                 before_view_objid        int                    NULL,
  4682.                 verify_resolver_signature         int            NULL,
  4683.                 allow_interactive_resolver        bit            NOT NULL default 0,
  4684.                 fast_multicol_updateproc        bit            NOT NULL default 0,
  4685.                 check_permissions        int                    NOT NULL default 0,
  4686.                 maxversion_at_cleanup    int                    NOT NULL default 1,
  4687.                 published_in_tran_pub    bit                    NOT NULL default 0
  4688.                 
  4689.                 -- Note: Please update sysmergeextendedarticlesview whenever
  4690.                 -- there is a schema change in sysmergearticles
  4691.             )
  4692.         
  4693.             if @@error<>0
  4694.                 goto Error
  4695.             else
  4696.                 begin
  4697.                     
  4698.                     create unique clustered index uc1sysmergearticles
  4699.                         on sysmergearticles(artid, pubid) 
  4700.                     if @@ERROR <> 0
  4701.                         goto Error
  4702.                     
  4703.                     if not exists (select * from sysindexes where name = 'nc1sysmergearticles')
  4704.                     begin
  4705.                         create nonclustered index nc1sysmergearticles on sysmergearticles(nickname) 
  4706.                         if @@ERROR <> 0
  4707.                         return 1
  4708.                     end
  4709.                 end
  4710.             exec dbo.sp_MS_marksystemobject sysmergearticles
  4711.             if @@ERROR <> 0
  4712.                 goto Error
  4713.             grant select(nickname,gen_cur,maxversion_at_cleanup) on sysmergearticles to public
  4714.             
  4715.         end
  4716.  
  4717.     if not exists (select * from sysobjects where name = 'sysmergeschemaarticles')
  4718.         begin
  4719.             
  4720.             -- The extended merge articles table is for storing 
  4721.             -- schema only article information. 
  4722.             -- The current supported schema only articles are
  4723.             -- stored procs and views.
  4724.             raiserror('Creating table sysmergeschemaarticles',0,1)
  4725.  
  4726.             create table dbo.sysmergeschemaarticles 
  4727.             (   name                    sysname             NOT NULL,
  4728.                 type                    tinyint             NULL,
  4729.                 objid                   int                 NOT NULL,
  4730.                 artid                   uniqueidentifier    NOT NULL,
  4731.                 description             nvarchar(255)       NULL,
  4732.                 pre_creation_command    tinyint             NULL,
  4733.                 pubid                   uniqueidentifier    NOT NULL,
  4734.                 status                  tinyint             NULL,
  4735.                 creation_script         nvarchar(255)       NULL,
  4736.                 schema_option           binary(8)           NULL,
  4737.                 destination_object      sysname             NOT NULL,
  4738.                 destination_owner       sysname             NULL
  4739.                 -- Note: Please update sysmergeextendedarticlesview whenever
  4740.                 -- there is a schema change in sysmergeschemaarticles
  4741.             )
  4742.             
  4743.             if @@error<>0
  4744.                 goto Error
  4745.             else
  4746.                 begin
  4747.                     create unique clustered index uc1sysmergeschemaarticles
  4748.                         on sysmergeschemaarticles(artid, pubid)
  4749.                         if @@ERROR <> 0
  4750.                             goto Error
  4751.                 end
  4752.  
  4753.             exec dbo.sp_MS_marksystemobject sysmergeschemaarticles
  4754.             if @@ERROR <> 0
  4755.                 goto Error
  4756.  
  4757.         end
  4758.  
  4759.     if exists (select * from sysobjects where name = 'sysmergeextendedarticlesview')
  4760.     begin
  4761.         drop view dbo.sysmergeextendedarticlesview
  4762.     end
  4763.     exec ('create view dbo.sysmergeextendedarticlesview
  4764.                as
  4765.            select name, type, objid, sync_objid, view_type, artid, description, pre_creation_command, pubid,
  4766.                   nickname, column_tracking, status, conflict_table, creation_script, conflict_script, article_resolver,
  4767.                   ins_conflict_proc, insert_proc, update_proc, select_proc, schema_option, destination_object,
  4768.                   resolver_clsid, subset_filterclause, missing_col_count, missing_cols, columns, resolver_info,
  4769.                   view_sel_proc, gen_cur, excluded_cols, excluded_col_count, vertical_partition, identity_support,
  4770.                   destination_owner, before_image_objid, before_view_objid, verify_resolver_signature, 
  4771.                   allow_interactive_resolver, fast_multicol_updateproc, check_permissions, maxversion_at_cleanup,
  4772.                   published_in_tran_pub
  4773.            from sysmergearticles
  4774.            union all
  4775.            select name, type, objid, NULL, NULL, artid, description, pre_creation_command, pubid, 
  4776.                   NULL, NULL, status, NULL, creation_script, NULL, NULL, 
  4777.                   NULL, NULL, NULL, NULL, schema_option, destination_object, 
  4778.                   NULL, NULL, NULL, NULL, NULL, NULL, 
  4779.                   NULL, NULL, NULL, NULL, NULL, NULL, 
  4780.                   destination_owner, NULL, NULL, NULL, 
  4781.                   0, 0, 0, NULL, 0
  4782.                   from sysmergeschemaarticles
  4783.                   go')            
  4784.     if @@error <> 0
  4785.         goto Error
  4786.  
  4787.     exec dbo.sp_MS_marksystemobject sysmergeextendedarticlesview
  4788.  
  4789.     if not exists (select * from sysobjects    where name = 'sysmergesubscriptions')
  4790.         begin
  4791.         
  4792.             raiserror('Creating table sysmergesubscriptions',0,1)
  4793.  
  4794.             
  4795.             create table dbo.sysmergesubscriptions
  4796.             (
  4797.                 subid                 uniqueidentifier     NOT NULL,
  4798.                 partnerid             uniqueidentifier     NOT NULL,
  4799.                 datasource_type        int                    NOT NULL,
  4800.                 datasource_path        nvarchar(255)        NULL,
  4801.                 srvid                 int                    NOT NULL,
  4802.                 db_name                  sysname                 NOT NULL
  4803.                 constraint             unique_pubsrvdb     unique nonclustered (pubid, srvid, db_name),
  4804.                 pubid                uniqueidentifier     NULL,
  4805.                 status                tinyint             NOT NULL,
  4806.                 subscriber_type        int                    NOT NULL,
  4807.                 subscription_type    int                    NOT NULL,
  4808.                 priority            real                NOT NULL,
  4809.                 sync_type             tinyint                NOT NULL,    -- 1 = automatic 2 = no sync
  4810.                 description            nvarchar(255)        NULL,
  4811.                 login_name            sysname                NOT NULL,
  4812.                 last_validated        datetime            NULL,
  4813.                 subscriber_server    sysname                NULL,
  4814.                 use_interactive_resolver        bit        NOT NULL default 0,
  4815.                 publication            sysname                 NULL,
  4816.                 distributor            sysname                 NULL,
  4817.                 validation_level    int                    not NULL default 0,
  4818.                 resync_gen            int                    not NULL default -1,
  4819.                 attempted_validate    datetime            NULL,
  4820.                 last_sync_date        datetime            NULL,
  4821.                 last_sync_status    int                    NULL,
  4822.                 last_sync_summary    sysname                NULL
  4823.             )
  4824.         
  4825.             if @@error<>0
  4826.                 goto Error
  4827.             else
  4828.                 begin
  4829.                     create unique clustered index uc1sysmergesubscriptions 
  4830.                         on sysmergesubscriptions (subid) 
  4831.                     if @@ERROR<>0
  4832.                         goto Error
  4833.  
  4834.                     create index nc2sysmergesubscriptions on sysmergesubscriptions (srvid, db_name)
  4835.                     if @@ERROR<>0
  4836.                         goto Error
  4837.                 end
  4838.             exec dbo.sp_MS_marksystemobject sysmergesubscriptions
  4839.             if @@ERROR <> 0
  4840.                 goto Error
  4841.             --grant select on sysmergesubscriptions to public
  4842.             
  4843.         end
  4844.  
  4845.     if not exists (select * from sysobjects    where name = 'MSmerge_replinfo')
  4846.         begin
  4847.             raiserror('Creating table MSmerge_replinfo',0,1)
  4848.             
  4849.             create table dbo.MSmerge_replinfo
  4850.             (
  4851.                 repid                     uniqueidentifier     NOT NULL,
  4852.                 replnickname            int                    NOT NULL,
  4853.                 recgen                    int                 NULL,
  4854.                 recguid                    uniqueidentifier     NULL,
  4855.                 sentgen                    int                 NULL,
  4856.                 sentguid                uniqueidentifier     NULL,
  4857.                 schemaversion            int                 NULL,
  4858.                 schemaguid                uniqueidentifier     NULL,
  4859.                 merge_jobid                binary(16)            NULL,
  4860.                 snapshot_jobid            binary(16)            NULL
  4861.             )
  4862.         
  4863.             if @@ERROR <> 0
  4864.                 goto Error
  4865.             else
  4866.                 begin
  4867.                     create unique clustered index uc1MSmerge_replinfo
  4868.                         on MSmerge_replinfo (repid)
  4869.                     if @@ERROR <> 0
  4870.                         goto Error
  4871.                 end
  4872.             exec dbo.sp_MS_marksystemobject MSmerge_replinfo
  4873.             if @@ERROR <> 0
  4874.                 goto Error
  4875.             --grant select on MSmerge_replinfo to public
  4876.             
  4877.         end
  4878.  
  4879.     if not exists (select * from sysobjects    where name = 'MSmerge_tombstone')
  4880.         begin
  4881.             raiserror('Creating table MSmerge_tombstone',0,1)
  4882.             
  4883.             create table dbo.MSmerge_tombstone
  4884.             (
  4885.                 rowguid            uniqueidentifier rowguidcol NOT NULL,
  4886.                 tablenick        int                NOT NULL,
  4887.                 type            tinyint            NOT NULL,
  4888.                 lineage            varbinary(249)    NOT NULL,
  4889.                 generation        int                NOT NULL,
  4890.                 reason            nvarchar(255)    NOT NULL,
  4891.             )
  4892.  
  4893.             if @@ERROR <> 0
  4894.                 goto Error
  4895.             else
  4896.             begin
  4897.                 create unique clustered index uc1MSmerge_tombstone
  4898.                     on MSmerge_tombstone (tablenick DESC, rowguid) 
  4899.                 if @@ERROR <> 0    goto Error
  4900.                 
  4901.                 create index nc2MSmerge_tombstone
  4902.                     on MSmerge_tombstone (generation) 
  4903.                 if @@ERROR <> 0    goto Error
  4904.             end    
  4905.     
  4906.              exec dbo.sp_MS_marksystemobject MSmerge_tombstone
  4907.              if @@ERROR <> 0
  4908.                 goto Error
  4909.             --grant select on MSmerge_tombstone to public
  4910.             
  4911.         end
  4912.  
  4913.     if not exists (select * from sysobjects    where name = 'MSmerge_contents')
  4914.         begin
  4915.             raiserror('Creating table MSmerge_contents',0,1)
  4916.             
  4917.             create table dbo.MSmerge_contents
  4918.             (
  4919.                 tablenick        int                    NOT NULL,
  4920.                 rowguid            uniqueidentifier rowguidcol   NOT NULL,
  4921.                 generation        int                    NOT NULL,
  4922.                 partchangegen    int                    NULL,
  4923.                 joinchangegen    int                    NULL,
  4924.                 lineage            varbinary(249)        NOT NULL,
  4925.                 colv1            varbinary(2048)        NULL,
  4926.             )
  4927.         
  4928.             if @@ERROR <> 0
  4929.                 goto Error
  4930.             else
  4931.             begin
  4932.                 create unique clustered index uc1SycContents on MSmerge_contents(tablenick, rowguid)
  4933.                 if @@ERROR <> 0 goto Error
  4934.                 create index nc2MSmerge_contents on MSmerge_contents(generation) 
  4935.                 if @@ERROR <> 0 goto Error
  4936.                 create index nc3MSmerge_contents on MSmerge_contents(partchangegen) 
  4937.                 if @@ERROR <> 0 goto Error
  4938.                 create index nc4MSmerge_contents on MSmerge_contents(rowguid) 
  4939.                 if @@ERROR <> 0 goto Error
  4940.             end
  4941.             exec dbo.sp_MS_marksystemobject MSmerge_contents
  4942.             if @@ERROR <> 0
  4943.                 goto Error
  4944.             --grant select on MSmerge_contents to public
  4945.             
  4946.         end                
  4947.  
  4948.     if not exists (select * from sysobjects    where name = 'MSmerge_genhistory')
  4949.         begin
  4950.             raiserror('Creating table MSmerge_genhistory',0,1)
  4951.             
  4952.             create table dbo.MSmerge_genhistory
  4953.             (
  4954.                 guidsrc         uniqueidentifier     NOT NULL,
  4955.                 guidlocal         uniqueidentifier     NOT NULL,
  4956.                 pubid            uniqueidentifier     NULL,
  4957.                 generation         int                    NOT NULL,
  4958.                 art_nick        int                    NULL,
  4959.                 nicknames        varbinary(1000)        NOT NULL,
  4960.                 coldate         datetime            NOT NULL
  4961.             )
  4962.                     
  4963.             if @@ERROR <> 0
  4964.                 goto Error
  4965.  
  4966.             create clustered index c1MSmerge_genhistory on MSmerge_genhistory(generation) 
  4967.             if @@ERROR <> 0
  4968.                 goto Error
  4969.  
  4970.             create unique index unc1MSmerge_genhistory on MSmerge_genhistory(guidsrc, pubid) 
  4971.             if @@ERROR <> 0
  4972.                 goto Error
  4973.  
  4974.             create  index nc2MSmerge_genhistory on MSmerge_genhistory(guidlocal) 
  4975.             if @@ERROR <> 0
  4976.                 goto Error
  4977.  
  4978.             CREATE INDEX nc4MSmerge_genhistory ON MSmerge_genhistory(coldate)        
  4979.             if @@ERROR <> 0
  4980.                 goto Error
  4981.  
  4982.              exec dbo.sp_MS_marksystemobject MSmerge_genhistory
  4983.              if @@ERROR <> 0
  4984.                 goto Error
  4985.             --grant select on MSmerge_genhistory to public
  4986.             
  4987.         end
  4988.  
  4989.     if not exists (select * from sysobjects    where name = 'MSmerge_delete_conflicts')
  4990.         begin
  4991.  
  4992.             raiserror('Creating table MSmerge_delete_conflicts',0,1)
  4993.             
  4994.             create table dbo.MSmerge_delete_conflicts
  4995.             (
  4996.                 tablenick            int                NOT NULL,
  4997.                 rowguid                uniqueidentifier rowguidcol NOT NULL,
  4998.                 origin_datasource    nvarchar(255)    NULL,
  4999.                 conflict_type        int NULL,
  5000.                 reason_code            int NULL,
  5001.                 reason_text            nvarchar(720)     NULL,
  5002.                 pubid                uniqueidentifier NULL,
  5003.                 create_time            datetime not null default getdate()
  5004.             )
  5005.         
  5006.             if @@ERROR <> 0
  5007.                 goto Error
  5008.             else
  5009.                 begin
  5010.                     create clustered index uc1MSmerge_delete_conflicts on MSmerge_delete_conflicts(tablenick, rowguid) 
  5011.                     if @@ERROR <> 0
  5012.                         goto Error
  5013.                 end                    
  5014.  
  5015.             CREATE UNIQUE NONCLUSTERED INDEX nc1MSmerge_delete_conflicts 
  5016.                     ON MSmerge_delete_conflicts(tablenick, rowguid, origin_datasource)
  5017.             if @@ERROR <> 0
  5018.                         goto Error
  5019.  
  5020.             exec dbo.sp_MS_marksystemobject MSmerge_delete_conflicts
  5021.             if @@ERROR <> 0
  5022.                 goto Error
  5023.             --grant select on MSmerge_delete_conflicts to public
  5024.             
  5025.         end
  5026.  
  5027.     if not exists (select * from sysobjects    where name = 'sysmergeschemachange')
  5028.         begin
  5029.         
  5030.             raiserror('Creating table sysmergeschemachange',0,1)
  5031.             
  5032.             create table dbo.sysmergeschemachange
  5033.             (
  5034.                 pubid            uniqueidentifier     NOT NULL,
  5035.                 artid            uniqueidentifier     NULL,
  5036.                 schemaversion     int                NOT NULL,
  5037.                 schemaguid        uniqueidentifier     NOT NULL,
  5038.                 schematype        int                  NOT NULL,
  5039.                 schematext        nvarchar(2000)     NOT NULL
  5040.             )
  5041.         
  5042.             if @@ERROR <> 0
  5043.                 goto Error
  5044.             else
  5045.                 begin
  5046.                     create unique clustered index schemachangeversion on sysmergeschemachange(schemaversion, pubid) 
  5047.                     if @@ERROR <> 0
  5048.                         goto Error
  5049.                 end
  5050.             exec dbo.sp_MS_marksystemobject sysmergeschemachange
  5051.             if @@ERROR <> 0
  5052.                 goto Error
  5053.             --grant select on sysmergeschemachange to public
  5054.             
  5055.         end
  5056.  
  5057.     if not exists (select * from sysobjects where name = 'sysmergesubsetfilters')
  5058.         begin
  5059.             raiserror('Creating table sysmergesubsetfilters',0,1)
  5060.  
  5061.             
  5062.             create table dbo.sysmergesubsetfilters (
  5063.                 filtername              sysname                 NOT NULL,
  5064.                 join_filterid            int                    identity NOT NULL,
  5065.                 pubid                    uniqueidentifier    NOT NULL,
  5066.                 artid                    uniqueidentifier    NOT NULL,
  5067.                 art_nickname            int                    NOT NULL,
  5068.                 join_articlename        sysname NOT NULL,
  5069.                 join_nickname             int                    NOT NULL,
  5070.                 join_unique_key            int                    NOT NULL,
  5071.                 expand_proc                sysname                    NULL,
  5072.                 join_filterclause        nvarchar(1000)          NULL
  5073.             )
  5074.             if @@ERROR <> 0
  5075.                 goto Error
  5076.  
  5077.             CREATE UNIQUE NONCLUSTERED INDEX nc1sysmergesubsetfilters 
  5078.                 ON sysmergesubsetfilters(join_filterid, pubid)
  5079.             if @@ERROR <> 0
  5080.                 goto Error
  5081.  
  5082.             exec dbo.sp_MS_marksystemobject sysmergesubsetfilters
  5083.             if @@ERROR <> 0
  5084.                 goto Error
  5085.             --grant select on sysmergesubsetfilters to public
  5086.             
  5087.         end
  5088.  
  5089.     if @@error <> 0
  5090.         goto Error
  5091.  
  5092.     if not exists (select * from sysobjects where name = 'MSdynamicsnapshotviews')
  5093.         begin
  5094.             raiserror('Creating table MSdynamicsnapshotviews',0,1)
  5095.             
  5096.             create table dbo.MSdynamicsnapshotviews (
  5097.                 dynamic_snapshot_view_name sysname primary key
  5098.             )
  5099.             if @@ERROR <> 0
  5100.                 goto Error
  5101.             exec dbo.sp_MS_marksystemobject MSdynamicsnapshotviews
  5102.         end
  5103.  
  5104.     if not exists (select * from sysobjects where name = 'MSdynamicsnapshotjobs')
  5105.         begin
  5106.             raiserror('Creating table MSdynamicsnapshotjobs',0,1)
  5107.         
  5108.             create table dbo.MSdynamicsnapshotjobs (
  5109.                 id int identity, 
  5110.                 name sysname not null unique,
  5111.                 pubid uniqueidentifier not null,
  5112.                 job_id uniqueidentifier not null,
  5113.                 dynamic_filter_login sysname null,
  5114.                 dynamic_filter_hostname sysname null,
  5115.                 dynamic_snapshot_location nvarchar(255) not null
  5116.             )
  5117.             if @@ERROR <> 0
  5118.                 goto Error
  5119.  
  5120.             exec dbo.sp_MS_marksystemobject MSdynamicsnapshotjobs
  5121.  
  5122.             create unique clustered index uciMSdynamicsnapshotjobs on 
  5123.                 dbo.MSdynamicsnapshotjobs(job_id, pubid)
  5124.             
  5125.             if @@ERROR <> 0
  5126.                 goto Error
  5127.  
  5128.  
  5129.         end
  5130.     
  5131.     if @@error <> 0
  5132.         goto Error
  5133.  
  5134.     if not exists (select * from sysobjects where name = 'MSmerge_altsyncpartners')
  5135.         begin
  5136.             raiserror('Creating table MSmerge_altsyncpartners',0,1)
  5137.         
  5138.             create table dbo.MSmerge_altsyncpartners (
  5139.                 subid                 uniqueidentifier     not null,
  5140.                 alternate_subid     uniqueidentifier     not null,
  5141.                 description            nvarchar(255)        NULL
  5142.  
  5143.             )
  5144.             if @@ERROR <> 0
  5145.                 goto Error
  5146.  
  5147.             exec dbo.sp_MS_marksystemobject MSmerge_altsyncpartners
  5148.  
  5149.             create unique clustered index uciMSmerge_altsyncpartners on 
  5150.                 dbo.MSmerge_altsyncpartners(subid, alternate_subid)
  5151.             
  5152.             if @@ERROR <> 0
  5153.                 goto Error
  5154.  
  5155.  
  5156.         end
  5157.     
  5158.  
  5159.     if exists (select * from master..sysobjects where type='P' and name='sp_MScreatedebuginfrastructure')
  5160.     begin
  5161.         declare @retval int
  5162.         exec @retval= dbo.sp_MScreatedebuginfrastructure
  5163.         if @@ERROR <> 0 or @retval <> 0 goto Error
  5164.     end
  5165.     
  5166.     commit transaction
  5167.     return (0)
  5168. Error:
  5169.     if @@trancount > 0
  5170.     begin
  5171.         ROLLBACK TRANSACTION MScreate_mergesystables
  5172.         COMMIT TRANSACTION
  5173.     end
  5174.     RAISERROR (20008, 16, -1)
  5175.     return (1)
  5176. go
  5177.  
  5178. exec dbo.sp_MS_marksystemobject sp_MScreate_mergesystables 
  5179. go
  5180.  
  5181. raiserror('Creating procedure sp_MStestbit',0,1)
  5182. go
  5183. create procedure sp_MStestbit
  5184.             @bm varbinary(128),
  5185.             @coltotest smallint
  5186. AS
  5187.             declare @word smallint
  5188.             declare @bit  smallint
  5189.             declare @mask binary(2)
  5190.             declare @mval int
  5191.             declare @oldword binary(2)  
  5192.  
  5193.             if @coltotest < 1 return 0
  5194.  
  5195.             SELECT @word = 1 + FLOOR((@coltotest -1)/16)
  5196.  
  5197.             SELECT @bit = (@coltotest -1) % 16
  5198.  
  5199.             SELECT @mval = POWER(2, @bit)
  5200.             SELECT @mask = convert( binary(2), unicode( substring( convert( nchar(2), convert( binary(4), @mval ) ), 2, 1 ) ) )
  5201.             
  5202.             SELECT @oldword = convert( binary(2), SUBSTRING( convert( nvarchar(64),@bm), @word, 1) )
  5203.             IF @oldword IS NULL return 0
  5204.  
  5205.             return  convert( smallint, @oldword ) & convert( smallint, @mask )
  5206. go
  5207. exec dbo.sp_MS_marksystemobject sp_MStestbit
  5208. go
  5209. grant exec on dbo.sp_MStestbit to public
  5210.         
  5211. raiserror('Creating procedure sp_MSsetbit',0,1)
  5212. go
  5213. set ansi_padding on
  5214. go
  5215. create procedure sp_MSsetbit
  5216.     @bm varbinary(128) output,
  5217.     @coltoadd smallint,
  5218.     @toset    int = 1
  5219. AS
  5220.     declare @bytenum smallint
  5221.     declare @bit smallint
  5222.     declare @mask tinyint
  5223.     declare @newbyte tinyint     
  5224.     declare @oldbyte tinyint
  5225.             
  5226.     SELECT @bytenum = 1 + FLOOR((@coltoadd-1)/8)
  5227.  
  5228.     IF @bytenum > 128 return 0
  5229.  
  5230.     SELECT @bit = (@coltoadd-1) % 8
  5231.  
  5232.     SET @mask = POWER(2, @bit)
  5233.     if @toset = 0
  5234.         SET @mask = (~@mask % 256)
  5235.                 
  5236.     if @bm is null
  5237.         set @bm = 0x0
  5238.     while datalength(@bm) < @bytenum
  5239.         set @bm = @bm + 0x00 
  5240.  
  5241.     SET @oldbyte = SUBSTRING( @bm, @bytenum, 1)
  5242.     IF @oldbyte IS NULL SET @oldbyte = 0
  5243.     if @toset <> 0            
  5244.         SET @newbyte = @oldbyte | @mask
  5245.     else
  5246.         SET @newbyte = @oldbyte & @mask
  5247.  
  5248.     if (@bytenum = 1)
  5249.         set @bm = convert(binary(1), @newbyte) + substring(@bm, 2, 127)
  5250.     else
  5251.         set @bm = substring(@bm, 1, @bytenum - 1) + convert(binary(1), @newbyte) + substring(@bm, @bytenum + 1, 128 - @bytenum)
  5252. go
  5253. exec dbo.sp_MS_marksystemobject sp_MSsetbit
  5254. go
  5255. grant exec on dbo.sp_MSsetbit to public
  5256.  
  5257. raiserror('Creating procedure sp_MSinsertcontents',0,1)
  5258. go
  5259. create procedure sp_MSinsertcontents
  5260.                 @tablenick int,
  5261.                 @rowguid uniqueidentifier,
  5262.                  @lineage varbinary(249),
  5263.                  @colv1 varbinary(2048)
  5264. AS
  5265.                 /*
  5266.                 ** permission check
  5267.                 */
  5268.                 declare @retcode    int
  5269.                 declare @objid        int
  5270.                 declare @owner        sysname
  5271.                 declare @artid        uniqueidentifier
  5272.                 declare @guidstr    nvarchar(32)    
  5273.                 declare @instrigger nvarchar(270)
  5274.                 
  5275.                 select @objid = objid, @artid=artid from sysmergearticles where nickname=@tablenick
  5276.                 select @owner =user_name(uid) from sysobjects where id=@objid
  5277.  
  5278.                 exec @retcode=sp_MSguidtostr @artid, @guidstr out
  5279.                     if @retcode<>0 or @@ERROR<>0 return (1)
  5280.  
  5281.                 set @instrigger = QUOTENAME(@owner) + '.ins_' + @guidstr
  5282.  
  5283.                 if trigger_nestlevel(object_id(@instrigger)) = 0
  5284.                 begin
  5285.                     raiserror(14126, 16, -1)
  5286.                     return (1) -- current user does not have insert permission to underlying table
  5287.                 end
  5288.             
  5289.                 insert into MSmerge_contents (tablenick, rowguid, generation, partchangegen, joinchangegen, lineage, colv1)
  5290.                     values (@tablenick, @rowguid, 0, 0, 0, @lineage, @colv1)
  5291.                 if @@error <> 0
  5292.                     begin
  5293.                     raiserror (20041, 16, -1)
  5294.                     return (1)
  5295.                     end            
  5296.  
  5297.                 delete from MSmerge_tombstone where rowguid = @rowguid and tablenick = @tablenick         
  5298.                 if @@error <> 0
  5299.                     begin
  5300.                     raiserror (20041, 16, -1)
  5301.                     return (1)
  5302.                     end    
  5303.  
  5304. go
  5305. exec dbo.sp_MS_marksystemobject sp_MSinsertcontents
  5306. go
  5307.  
  5308. raiserror('Creating procedure sp_MSupdatecontents',0,1)
  5309. go
  5310. create procedure sp_MSupdatecontents
  5311.                  @tablenick int,
  5312.                  @rowguid uniqueidentifier,
  5313.                  @lineage varbinary(249),
  5314.                  @colv1 varbinary(2048),
  5315.                  @partchange int = null,
  5316.                  @joinchange int = null
  5317. AS
  5318.             /*
  5319.             ** permission check
  5320.             */
  5321.             declare @retcode    int
  5322.             declare @objid        int
  5323.             declare @owner        sysname
  5324.             declare @artid        uniqueidentifier
  5325.             declare @guidstr    nvarchar(32)    
  5326.             declare @updtrigger    nvarchar(270)
  5327.             
  5328.             select @objid = objid, @artid=artid from sysmergearticles where nickname=@tablenick
  5329.             select @owner =user_name(uid) from sysobjects where id=@objid
  5330.             
  5331.             exec @retcode=sp_MSguidtostr @artid, @guidstr out
  5332.                     if @retcode<>0 or @@ERROR<>0 return (1)
  5333.                     
  5334.                 set @updtrigger = QUOTENAME(@owner) + '.upd_' + @guidstr
  5335.  
  5336.                 if trigger_nestlevel(object_id(@updtrigger)) = 0
  5337.                 begin
  5338.                     raiserror(14126, 16, -1)
  5339.                     return (1) -- current user does not 'update all' permission upon underlying table
  5340.                 end
  5341.             
  5342.             update MSmerge_contents set lineage = @lineage, generation = 0, colv1 = @colv1
  5343.                 where tablenick = @tablenick and rowguid = @rowguid
  5344.             if (@@rowcount = 0)
  5345.                 insert into MSmerge_contents (tablenick, rowguid, generation, joinchangegen, lineage, colv1)
  5346.                     values (@tablenick, @rowguid, 0, 1, @lineage, @colv1)
  5347.             if @@error <> 0
  5348.                 begin
  5349.                 raiserror (20041, 16, -1)
  5350.                 return (1)
  5351.                 end
  5352.             if @partchange = 1
  5353.                 begin
  5354.                 update MSmerge_contents set partchangegen = 0, joinchangegen = 0
  5355.                     where tablenick = @tablenick and rowguid = @rowguid
  5356.                 if @@error <> 0
  5357.                     begin
  5358.                     raiserror (20041, 16, -1)
  5359.                     return (1)
  5360.                     end
  5361.                 end
  5362.             else if @joinchange = 1
  5363.                 begin
  5364.                 update MSmerge_contents set joinchangegen = 0
  5365.                     where tablenick = @tablenick and rowguid = @rowguid
  5366.                 if @@error <> 0
  5367.                     begin
  5368.                     raiserror (20041, 16, -1)
  5369.                     return (1)
  5370.                     end
  5371.                 end 
  5372. go
  5373. exec dbo.sp_MS_marksystemobject sp_MSupdatecontents
  5374. go
  5375.  
  5376. raiserror(15339, -1, -1, 'sp_MSdeletecontents')
  5377. go
  5378. create procedure sp_MSdeletecontents
  5379.     @tablenick int,
  5380.     @rowguid uniqueidentifier
  5381. AS
  5382.     declare @nick int
  5383.     declare @reason nvarchar(255)
  5384.     declare @lineage varbinary(255)
  5385.  
  5386.     /*
  5387.     ** permission check
  5388.     */
  5389.     declare @retcode    int
  5390.     declare @objid        int
  5391.     declare @owner        sysname
  5392.     declare @artid        uniqueidentifier
  5393.     declare @guidstr    nvarchar(32)    
  5394.     declare @deltrigger    nvarchar(270)
  5395.     declare @oldmaxversion int
  5396.     
  5397.     select @objid = objid, @artid=artid from sysmergearticles where nickname=@tablenick
  5398.     select @owner =user_name(uid) from sysobjects where id=@objid
  5399.     
  5400.     exec @retcode=sp_MSguidtostr @artid, @guidstr out
  5401.         if @retcode<>0 or @@ERROR<>0 return (1)
  5402.  
  5403.     set @deltrigger = QUOTENAME(@owner) + '.del_' + @guidstr
  5404.  
  5405.     if trigger_nestlevel(object_id(@deltrigger)) = 0
  5406.         begin
  5407.             raiserror(14126, 16, -1)
  5408.             return (1) -- current user does not have 'delete' permission to underlying table
  5409.         end
  5410.  
  5411.     exec dbo.sp_MSgetreplnick @nickname = @nick out
  5412.     if (@@error <> 0) or @nick IS NULL 
  5413.         begin
  5414.         RAISERROR (14055, 11, -1)
  5415.         RETURN(1)
  5416.         end                 
  5417.  
  5418.     select @oldmaxversion= maxversion_at_cleanup from sysmergearticles where nickname = @tablenick
  5419.     select @lineage = lineage from MSmerge_contents (UPDLOCK ROWLOCK index = 1) 
  5420.         where tablenick = @tablenick and rowguid = @rowguid
  5421.     set @lineage= { fn UPDATELINEAGE(@lineage, @nick, @oldmaxversion+1) }
  5422.     select @reason = 'user delete'
  5423.  
  5424.     insert into MSmerge_tombstone (rowguid, tablenick, type, lineage, generation, reason)
  5425.         values (@rowguid, @tablenick, 1, @lineage, 0, @reason)
  5426.     if @@error <> 0
  5427.         begin
  5428.         raiserror (20041, 16, -1)
  5429.         return (1)
  5430.         end
  5431.     delete from MSmerge_contents where
  5432.         tablenick = @tablenick and rowguid = @rowguid
  5433.     if @@error <> 0
  5434.         begin
  5435.         raiserror (20041, 16, -1)
  5436.         return (1)
  5437.         end 
  5438. go
  5439. exec dbo.sp_MS_marksystemobject sp_MSdeletecontents
  5440. go        
  5441.  
  5442.  
  5443. raiserror('Creating procedure sp_MSunmarkifneeded',0,1)
  5444. GO
  5445.  
  5446. CREATE PROCEDURE sp_MSunmarkifneeded(
  5447. @object                sysname,
  5448. @pubid                uniqueidentifier,
  5449. @pre_command         int = 0,
  5450. @publisher            sysname,
  5451. @publisher_db        sysname
  5452. )AS
  5453. declare @table_in_use    int
  5454. declare @retcode         int
  5455.  
  5456. select @table_in_use = 0
  5457. --if pre-creation_command is 'drop (1)' or 'truncate (3)', then disallow this deployment if there is already an article using that table.
  5458. --other commands like 'delete, truncate, none are fine'
  5459.  
  5460. if exists (select * from sysmergearticles where objid=object_id(@object) and pubid in
  5461.     (select pubid from sysmergepublications where LOWER(publisher)=LOWER(@publisher) and 
  5462.         publisher_db=@publisher_db and pubid<>@pubid))
  5463.     OR
  5464.     ((@pre_command=1 or @pre_command=3) and 
  5465.         EXISTS (select * from sysmergearticles where objid=object_id(@object) and pubid <> @pubid and pubid not in
  5466.             (select pubid from sysmergepublications where LOWER(publisher)=LOWER(@@SERVERNAME) and publisher_db=db_name())))  
  5467. begin
  5468.     select @table_in_use = 1
  5469.     select @table_in_use
  5470.     return (0)
  5471. end
  5472. exec @retcode = sp_MSunmarkreplinfo @object
  5473. if @retcode <>0 or @@error<>0
  5474.     return (1)
  5475. select @table_in_use 
  5476. return (0)
  5477. GO
  5478. exec dbo.sp_MS_marksystemobject sp_MSunmarkifneeded
  5479. go        
  5480. grant exec on dbo.sp_MSunmarkifneeded to public
  5481. go
  5482.  
  5483. raiserror('Creating procedure sp_MSunmarkreplinfo',0,1)
  5484. GO
  5485.  
  5486. CREATE PROCEDURE sp_MSunmarkreplinfo(
  5487.     @object                sysname,            /* Name of the table, unqualitied */
  5488.     @owner                sysname = NULL,            /* Name of the owner, unqualified */
  5489.     @type                smallint = 0        /* default is to unmark, as name implies */
  5490. )AS
  5491. declare @merge_pub_object_bit int
  5492. declare @merge_pub_unmark_bit int
  5493. declare @id    int
  5494. declare @qualified_name            nvarchar(270)
  5495. declare @retcode                int
  5496.  
  5497. exec @retcode = sp_MSreplcheck_subscribe
  5498. if @@error<>0 or @retcode<>0
  5499.     return (1)
  5500.  
  5501. if @owner is NULL or @owner=''
  5502.     select @owner = user_name(uid) from sysobjects where name=@object
  5503. select @qualified_name = QUOTENAME(@owner) + '.' + QUOTENAME(@object) 
  5504.  
  5505.  
  5506. select @id = object_id(@qualified_name)
  5507.  
  5508. select @merge_pub_object_bit     = 128
  5509. select @merge_pub_unmark_bit = ~@merge_pub_object_bit
  5510.  
  5511. if exists (select name from sysobjects where id = @id) 
  5512.     begin
  5513.             if @type = 0    /* type = 0, unmark; else mark the bit */
  5514.         begin
  5515.             BEGIN TRANSACTION
  5516.                    exec dbo.sp_replupdateschema @qualified_name
  5517.                    update sysobjects set replinfo = replinfo & @merge_pub_unmark_bit where id = @id
  5518.                    exec dbo.sp_replupdateschema @qualified_name
  5519.             COMMIT TRANSACTION
  5520.         end
  5521.         else
  5522.         begin
  5523.             BEGIN TRANSACTION
  5524.                 exec dbo.sp_replupdateschema @qualified_name
  5525.                    update sysobjects set replinfo = replinfo | @merge_pub_object_bit where id = @id
  5526.                 exec dbo.sp_replupdateschema @qualified_name
  5527.                COMMIT TRANSACTION
  5528.         end
  5529.     end
  5530. GO
  5531. exec dbo.sp_MS_marksystemobject sp_MSunmarkreplinfo
  5532. go
  5533. grant execute on dbo.sp_MSunmarkreplinfo to public
  5534. go
  5535.  
  5536. /*
  5537. ** This is to have a better name 'sp_MSmarkreplinfo' while keeping the change minimal.
  5538. */
  5539. raiserror('Creating procedure sp_MSmarkreplinfo',0,1)
  5540. GO
  5541. CREATE PROCEDURE sp_MSmarkreplinfo(
  5542.     @object                sysname,            /* Name of the table, unqualitied */
  5543.     @owner                sysname = NULL        /* Name of the owner, unqualified */
  5544. )AS
  5545. declare @retcode int
  5546.  
  5547. exec @retcode = sp_MSunmarkreplinfo @object, @owner, 1
  5548. if @@ERROR<>0 or @retcode<>0
  5549.     return (1)
  5550. return (0)
  5551. GO
  5552. exec dbo.sp_MS_marksystemobject sp_MSmarkreplinfo
  5553. go
  5554.  
  5555.  
  5556. raiserror('Creating procedure sp_MSunmarkschemaobject',0,1)
  5557. go
  5558. CREATE PROCEDURE sp_MSunmarkschemaobject(
  5559.     @object           sysname,     
  5560.     @owner            sysname = NULL
  5561. )AS
  5562. begin
  5563. set nocount on
  5564. declare @schema_obj_bit_mask int
  5565. declare @qualified_name nvarchar(520)
  5566. declare @id int
  5567. declare @retcode int
  5568.  
  5569. exec @retcode = sp_MSreplcheck_subscribe
  5570. if @@error<>0 or @retcode <>0
  5571.     return (1)
  5572.  
  5573. select @schema_obj_bit_mask = 0x00000200
  5574. select @schema_obj_bit_mask = ~@schema_obj_bit_mask
  5575.  
  5576. if (@owner is null or @owner = N'')
  5577. begin
  5578.     select @owner = user_name()
  5579. end
  5580. select @qualified_name = QUOTENAME(@owner) + '.' + QUOTENAME(@object)
  5581.  
  5582. select @id = NULL
  5583. select @id = object_id(@qualified_name)
  5584.  
  5585. if (@id is not null)
  5586. begin
  5587.     begin transaction
  5588.     exec dbo.sp_replupdateschema @qualified_name
  5589.     update sysobjects set replinfo = replinfo & @schema_obj_bit_mask
  5590.     where id = @id
  5591.     exec dbo.sp_replupdateschema @qualified_name
  5592.     commit transaction
  5593. end
  5594. return 0    
  5595. end
  5596. go
  5597. exec dbo.sp_MS_marksystemobject sp_MSunmarkschemaobject
  5598. go
  5599. grant execute on dbo.sp_MSunmarkschemaobject to public
  5600. go
  5601.  
  5602. raiserror('Creating procedure sp_MSmarkschemaobject',0,1)
  5603. go
  5604. CREATE PROCEDURE sp_MSmarkschemaobject(
  5605.     @object           sysname,
  5606.     @owner            sysname = NULL
  5607. )AS
  5608. begin
  5609. set nocount on
  5610. declare @schema_obj_bit_mask int
  5611. declare @qualified_name nvarchar(520)
  5612. declare @id int
  5613. declare @retcode int
  5614.  
  5615. exec @retcode = sp_MSreplcheck_subscribe
  5616. if @@error<>0 or @retcode<>0
  5617.     return (1)
  5618.  
  5619. select @schema_obj_bit_mask = 0x00000200
  5620.  
  5621. if (@owner is null or @owner = N'')
  5622. begin
  5623.     select @owner = user_name()
  5624. end
  5625. select @qualified_name = QUOTENAME(@owner) + '.' + QUOTENAME(@object)
  5626.  
  5627. select @id = NULL
  5628. select @id = object_id(@qualified_name)
  5629.  
  5630. if (@id is not null)
  5631. begin
  5632.     begin transaction
  5633.     exec dbo.sp_replupdateschema @qualified_name
  5634.     update sysobjects set replinfo = replinfo | @schema_obj_bit_mask
  5635.     where id = @id
  5636.     exec dbo.sp_replupdateschema @qualified_name
  5637.     commit transaction
  5638. end
  5639. return 0
  5640. end
  5641. go
  5642. exec dbo.sp_MS_marksystemobject sp_MSmarkschemaobject
  5643. go
  5644.  
  5645. raiserror('Creating procedure sp_MSaddanonymousreplica',0,1)
  5646. GO
  5647. CREATE PROCEDURE sp_MSaddanonymousreplica
  5648.     (@publication         sysname,
  5649.      @publisher            sysname,
  5650.      @publisherDB        sysname,
  5651.      @anonymous            int,
  5652.      @sync_type            int = 1, /* sync type is automatic by default */
  5653.      @preexists            bit=0 OUTPUT
  5654. )
  5655. as
  5656. set nocount on
  5657. declare @retcode                 int
  5658. declare @subscription_type         nvarchar(15)
  5659. declare @sync_typestr             nvarchar(15)
  5660. declare @sub_typeid                int
  5661. declare @pubid                    uniqueidentifier
  5662.  
  5663. /*
  5664. ** need more than PAL to do this.
  5665. */
  5666. exec @retcode = sp_MSreplcheck_subscribe
  5667. if @@error<>0 or @retcode<>0
  5668.     return (1)
  5669.  
  5670. select @preexists = 0
  5671.  
  5672. if @anonymous = 1 
  5673. begin
  5674.     select @subscription_type = 'anonymous'
  5675.     select @sub_typeid    = 2 --subscription type value for anonymous
  5676. end
  5677. else 
  5678. begin
  5679.     select @subscription_type = 'local'
  5680.     select @sub_typeid = 1 --subscription type value for well known pull
  5681. end
  5682.  
  5683. if @sync_type = 1 select @sync_typestr = 'automatic'
  5684.     else select @sync_typestr = 'none'
  5685.  
  5686. -- this change is made so that we will try to add pull/anonymous subscriptions, even if
  5687. -- there is a already a subscription for that publication, however the subscription type
  5688. -- does not match. In this way we can prevent users from using incorrect subscription type
  5689. -- through command line or merge control. 
  5690.  
  5691. if exists (select * from sysobjects where name='sysmergepublications')
  5692. begin
  5693.     select @pubid=pubid from sysmergepublications 
  5694.         where name=@publication and UPPER(publisher)=UPPER(@publisher) and publisher_db = @publisherDB
  5695.     if @pubid is not NULL
  5696.     begin
  5697.         /* Check if theres is a subscriptions entry that matches the pubid and current subscription with the right type */
  5698.         if exists (select * from sysmergesubscriptions where pubid =@pubid  and UPPER(subscriber_server) = @@SERVERNAME and db_name = DB_NAME() and subscription_type=@sub_typeid)
  5699.             begin
  5700.                 select @preexists = 1
  5701.                 return (0)   -- replica exists. 
  5702.             end
  5703.         /* 
  5704.         ** Check if theres is a subscriptions entry that matches the pubid and current subscription - 
  5705.         ** If there is a match and the types are not the same, then return appropriate error.
  5706.         */
  5707.         else if exists (select * from sysmergesubscriptions where pubid =@pubid  and UPPER(subscriber_server) = @@SERVERNAME and db_name = DB_NAME())
  5708.             begin
  5709.             RAISERROR (21500, 16, -1, @publication)    
  5710.             -- replica exists with wrong subscription type 
  5711.             select @preexists = 1
  5712.  
  5713.             return (1)   
  5714.             end
  5715.         
  5716.     end
  5717. end
  5718.  
  5719. -- Call this SP to add this replica
  5720. exec @retcode = dbo.sp_addmergepullsubscription 
  5721.     @publication = @publication,
  5722.     @publisher = @publisher,
  5723.     @publisher_db=@publisherDB,
  5724.     @subscriber_type =@subscription_type,
  5725.     @sync_type = @sync_typestr
  5726.  
  5727. IF @retcode<>0 or @@ERROR<>0 return (1)
  5728. return (0)
  5729. GO
  5730. exec dbo.sp_MS_marksystemobject sp_MSaddanonymousreplica
  5731. go
  5732. grant execute on dbo.sp_MSaddanonymousreplica to public
  5733. go 
  5734.  
  5735. raiserror('Creating procedure sp_MSgetreplicainfo',0,1)
  5736. GO
  5737. CREATE PROCEDURE sp_MSgetreplicainfo
  5738.     (@publisher            sysname,
  5739.      @publisher_db        sysname,
  5740.      @publication         sysname,
  5741.      @datasource_type    int = 0,                 /* 0 = SQL Server, 1 = DSN, 2 = Jet */
  5742.      @server_name        sysname    = NULL,         /* Server Name */
  5743.      @db_name            sysname = NULL,         /* Database Name */
  5744.      @datasource_path    nvarchar(255) = NULL)    /* Datasource path - JET MDB file path etc */
  5745.      
  5746. as
  5747.     declare        @srvid                int
  5748.     declare        @retcode            int
  5749.     declare        @repid                 uniqueidentifier
  5750.     declare        @pubid                 uniqueidentifier
  5751.     declare        @schemaguid            uniqueidentifier
  5752.     declare      @nickname             int
  5753.     declare     @subscription_type int
  5754.     declare     @validation_level    int
  5755.     declare     @reptype             tinyint
  5756.     declare     @priority             real 
  5757.     declare     @schversion         int 
  5758.     declare     @status                int
  5759.     declare     @resync_gen            int
  5760.     declare      @partnerid             uniqueidentifier
  5761.     declare     @sync_type             tinyint
  5762.     declare     @description         nvarchar(255)
  5763.     declare     @distributor        sysname
  5764.     
  5765.     /*
  5766.     ** Parameter Check:  @publication.
  5767.     ** Make sure that the publication exists.
  5768.     */
  5769.     if (@publication is null)
  5770.         begin
  5771.         RAISERROR(14043, 16, -1, '@publication')
  5772.         return (1)
  5773.         end
  5774.  
  5775.     if (@server_name is NULL)
  5776.         SET @server_name = @@SERVERNAME
  5777.  
  5778.     if (@db_name is NULL)
  5779.         set @db_name = db_name()
  5780.         
  5781.     SELECT @srvid = srvid FROM master..sysservers WHERE UPPER(srvname) = UPPER(@server_name) collate database_default
  5782.        IF @@ERROR <> 0
  5783.            BEGIN
  5784.             RAISERROR (14080, 16, -1)
  5785.              RETURN (1)
  5786.         END
  5787.  
  5788.     IF @srvid IS NULL
  5789.         BEGIN
  5790.             RAISERROR (14010, 16, -1)
  5791.             RETURN (1)
  5792.         END
  5793.  
  5794.     select @pubid = pubid from sysmergepublications 
  5795.         where name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db
  5796.     if (@pubid is null)
  5797.         begin
  5798.             RAISERROR (20026, 16, -1, @publication)
  5799.             return (1)
  5800.         end
  5801.  
  5802.     if (@datasource_type = 0)
  5803.         begin
  5804.             SELECT @repid = subid, @priority = priority, @reptype = subscriber_type, 
  5805.                 @subscription_type = subscription_type , @status = status, 
  5806.                 @partnerid = partnerid, @sync_type = sync_type, 
  5807.                 @description = description, @distributor = distributor, 
  5808.                 @validation_level=validation_level, @resync_gen=resync_gen
  5809.                 FROM sysmergesubscriptions
  5810.                 WHERE srvid = @srvid and db_name = @db_name and pubid = @pubid
  5811.         END
  5812.     ELSE
  5813.         BEGIN
  5814.             SELECT @repid = subid, @priority = priority, @reptype = subscriber_type, 
  5815.                 @subscription_type = subscription_type , @status = status, 
  5816.                 @partnerid = partnerid, @sync_type = sync_type, 
  5817.                 @description = description,@distributor = distributor, 
  5818.                     @validation_level=validation_level, @resync_gen=resync_gen
  5819.                 FROM sysmergesubscriptions
  5820.                 WHERE srvid = @srvid and pubid = @pubid
  5821.         END
  5822.  
  5823.     if @repid is NULL
  5824.         begin
  5825.             RAISERROR(20021, 16, -1)
  5826.             return (1)
  5827.         end
  5828.     select @schversion = schemaversion, @schemaguid = schemaguid from MSmerge_replinfo where repid = @repid
  5829.     select @nickname = replnickname from MSmerge_replinfo where repid = @repid
  5830.     select @repid, @nickname, @reptype, @subscription_type, @priority, @schversion, @schemaguid,
  5831.         @status, @partnerid, @sync_type, @description, @publication, @distributor, @validation_level, @resync_gen
  5832.     return (0)
  5833. go
  5834. exec dbo.sp_MS_marksystemobject sp_MSgetreplicainfo
  5835. go
  5836. grant execute on dbo.sp_MSgetreplicainfo to public
  5837.  
  5838.  
  5839. raiserror('Creating procedure sp_MSadd_repl_job',0,1)
  5840. go
  5841.  
  5842. CREATE PROCEDURE sp_MSadd_repl_job
  5843.   @name                   nvarchar(200),
  5844.   @subsystem              nvarchar(60)  = 'TSQL',
  5845.   @server                 sysname  = NULL,
  5846.   @username               sysname  = NULL,
  5847.   @databasename           sysname  = NULL,
  5848.   @enabled                TINYINT      = 0,
  5849.   @freqtype               INT          = 2, -- 2 means OnDemand
  5850.   @freqinterval           INT          = 1,
  5851.   @freqsubtype            INT          = 1,
  5852.   @freqsubinterval        INT          = 1,
  5853.   @freqrelativeinterval   INT          = 1,
  5854.   @freqrecurrencefactor   INT          = 1,
  5855.   @activestartdate        INT          = 0,
  5856.   @activeenddate          INT          = 0,
  5857.   @activestarttimeofday   INT          = 0,
  5858.   @activeendtimeofday     INT          = 0,
  5859.   @nextrundate            INT          = 0,
  5860.   @nextruntime            INT          = 0,
  5861.   @runpriority            INT          = 0,
  5862.   @emailoperatorname      nvarchar(100) = NULL,
  5863.   @retryattempts          INT          = NULL,
  5864.   @retrydelay             INT          = 0,
  5865.   @command                nvarchar(4000)= NULL,
  5866.   @loghistcompletionlevel INT          = 2,
  5867.   @emailcompletionlevel   INT          = 0,
  5868.   @description            nvarchar(255) = NULL,
  5869.   @tagadditionalinfo      nvarchar(96)  = NULL,
  5870.   @tagobjectid            INT          = NULL,
  5871.   @tagobjecttype          INT          = NULL,
  5872.   @cmdexecsuccesscode     INT          = 0,
  5873.   @category_name          sysname = NULL, -- New for 7.0
  5874.   @failure_detection      BIT           = 0,
  5875.   @agent_id               INT           = NULL,
  5876.   @job_id BINARY(16) = NULL OUTPUT
  5877. AS
  5878. BEGIN
  5879.   DECLARE   @retval INT
  5880.   declare   @step_id int
  5881.   declare   @step_name nvarchar(100)
  5882.   declare   @step_command nvarchar(1024)
  5883.   declare   @on_fail_action tinyint
  5884.   declare   @on_success_action tinyint
  5885.   declare   @schedule_name nvarchar(100)
  5886.   declare   @comments nvarchar(100)
  5887.  
  5888.   SET NOCOUNT ON
  5889.  
  5890.   SELECT @retval = 1 -- 0 means success, 1 means failure
  5891.   set @step_id = 1
  5892.   set @on_fail_action = 2   -- Return failure
  5893.   set @on_success_action = 1    -- Return success
  5894.   set @step_command = NULL
  5895.  
  5896.   /*
  5897.   ** Set default retries to every minute for 10 minutes.
  5898.   **
  5899.   */
  5900.   if @retryattempts = NULL and @retrydelay = 0
  5901.   begin
  5902.      select @retryattempts = 10
  5903.      select @retrydelay = 1
  5904.   end
  5905.  
  5906.   BEGIN TRANSACTION
  5907.   save tran sp_MSadd_repl_job
  5908.  
  5909.     -- Drop the job if it already exists
  5910.     IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE name = @name collate database_default)
  5911.     begin
  5912.         exec @retval = msdb.dbo.sp_delete_job @job_name=@name
  5913.         if @@ERROR<>0 or @retval<>0
  5914.             goto UNDO
  5915.     end
  5916.  
  5917.     -- Add the job
  5918.     EXECUTE @retval = msdb.dbo.sp_add_job
  5919.       @job_name                   = @name,
  5920.       @enabled                    = @enabled,
  5921.       @start_step_id              = 1,
  5922.       @description                = @description,
  5923.       @category_name              = @category_name,
  5924.       @notify_level_eventlog      = @loghistcompletionlevel,
  5925.       @notify_level_email         = @emailcompletionlevel,
  5926.       @notify_email_operator_name = @emailoperatorname,
  5927.       @job_id = @job_id OUTPUT
  5928.  
  5929.     IF (@retval <> 0)
  5930.     BEGIN
  5931.         GOTO UNDO
  5932.     END
  5933.  
  5934.     -- Add startup message step
  5935.     if @failure_detection = 1
  5936.     begin
  5937.  
  5938.         select @step_name = 
  5939.             case UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS)
  5940.                 when N'SNAPSHOT' then formatmessage(21410)
  5941.                 when N'LOGREADER' then formatmessage(20528)
  5942.                 when N'DISTRIBUTION' then formatmessage(21411)
  5943.                 when N'MERGE' then formatmessage(21412)
  5944.                 when N'QUEUEREADER' then formatmessage(21422)
  5945.             end 
  5946.         select @comments = formatmessage(20529)
  5947.  
  5948.         -- Construct command based on subsystem type
  5949.         select @step_command =
  5950.             case UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS) 
  5951.                 WHEN 'SNAPSHOT' THEN
  5952.                 N'sp_MSadd_snapshot_history @perfmon_increment = 0,  @agent_id = ' + 
  5953.                     convert (nvarchar(10), @agent_id) + N', @runstatus = 1,  
  5954.                     @comments = ''' + @comments + ''''
  5955.                 WHEN 'LOGREADER' THEN
  5956.                 N'sp_MSadd_logreader_history @perfmon_increment = 0, @agent_id = ' + 
  5957.                     convert (nvarchar(10), @agent_id) + N', @runstatus = 1, 
  5958.                     @comments = ''' + @comments + ''''
  5959.                 WHEN 'DISTRIBUTION' THEN
  5960.                 N'sp_MSadd_distribution_history @perfmon_increment = 0, @agent_id = ' + 
  5961.                     convert (nvarchar(10), @agent_id) + N', @runstatus = 1,  
  5962.                     @comments = ''' + @comments + ''''
  5963.                 WHEN 'MERGE' THEN
  5964.                 N'sp_MSadd_merge_history @perfmon_increment = 0, @agent_id = ' + 
  5965.                     convert (nvarchar(10),@agent_id) + N', @runstatus = 1,  
  5966.                     @comments = ''' + @comments + ''''
  5967.                 WHEN 'QUEUEREADER' THEN
  5968.                 N'sp_MSadd_qreader_history @perfmon_increment = 0, @agent_id = ' + 
  5969.                     convert (nvarchar(10), @agent_id) + N', @runstatus = 1,  
  5970.                     @comments = ''' + @comments + ''''                  
  5971.             end
  5972.     
  5973.         -- Add the job step
  5974.         EXECUTE @retval = msdb.dbo.sp_add_jobstep_internal
  5975.           @job_id                = @job_id,
  5976.           @step_id               = @step_id,
  5977.           @step_name             = @step_name,
  5978.           @command               = @step_command,
  5979.           @cmdexec_success_code  = @cmdexecsuccesscode,
  5980.           @on_success_action     = 3,   -- Goto next step
  5981.           @on_fail_action        = 3,   -- Goto next step
  5982.           @server                = @server,
  5983.           @database_name         = @databasename,
  5984.           @database_user_name    = @username,
  5985.           @os_run_priority       = @runpriority
  5986.  
  5987.         IF (@retval <> 0)
  5988.         BEGIN
  5989.             GOTO UNDO
  5990.         END
  5991.  
  5992.         set @step_id = @step_id + 1
  5993.         set @on_fail_action = 3         -- Goto next step
  5994.     end
  5995.  
  5996.     -- Add the job step
  5997.     select @step_name = formatmessage(20530)
  5998.     EXECUTE @retval = msdb.dbo.sp_add_jobstep_internal
  5999.     @job_id                = @job_id,
  6000.       @step_id               = @step_id,
  6001.       @step_name             = @step_name,
  6002.       @subsystem             = @subsystem,
  6003.       @command               = @command,
  6004.       @cmdexec_success_code  = @cmdexecsuccesscode,
  6005.       @on_success_action     = @on_success_action,
  6006.       @on_fail_action        = @on_fail_action,
  6007.       @server                = @server,
  6008.       @database_name         = @databasename,
  6009.       @database_user_name    = @username,
  6010.       @retry_attempts        = @retryattempts,
  6011.       @retry_interval        = @retrydelay,
  6012.       @os_run_priority       = @runpriority
  6013.  
  6014.     IF (@retval <> 0)
  6015.     BEGIN
  6016.         GOTO UNDO
  6017.     END
  6018.  
  6019.     -- Add failure message step
  6020.     if @failure_detection = 1
  6021.     begin
  6022.  
  6023.         set @step_id = @step_id + 1
  6024.  
  6025.         select @step_name = formatmessage(20531)
  6026.  
  6027.         -- Construct command
  6028.         select @step_command = N'sp_MSdetect_nonlogged_shutdown @subsystem = ''' + @subsystem +  N''', @agent_id = ' + convert (nvarchar(10),   @agent_id) 
  6029.  
  6030.         -- Add the job step
  6031.         EXECUTE @retval = msdb.dbo.sp_add_jobstep_internal
  6032.           @job_id                = @job_id,
  6033.           @step_id               = @step_id,
  6034.           @step_name             = @step_name,
  6035.           @command               = @step_command,
  6036.           @cmdexec_success_code  = @cmdexecsuccesscode,
  6037.           @on_success_action     = 2,                   -- Always quit with failure
  6038.           @server                = @server,
  6039.           @database_name         = @databasename,
  6040.           @database_user_name    = @username,
  6041.           @os_run_priority       = @runpriority
  6042.  
  6043.         IF (@retval <> 0)
  6044.         BEGIN
  6045.             GOTO UNDO
  6046.         END
  6047.     end
  6048.  
  6049.     -- Add the job schedule
  6050.     IF (@activestartdate = 0)
  6051.       SELECT @activestartdate = NULL
  6052.     IF (@activeenddate = 0)
  6053.       SELECT @activeenddate = NULL
  6054.     
  6055.     -- But if @activeenddate is NOT NULL, then @activestartdate cannot be allowed to be NULL either.  Set it to today's date converted to the int format used yyyymmdd
  6056.  
  6057.     IF (@activeenddate IS NOT NULL AND @activestartdate IS NULL)
  6058.     SELECT @activestartdate=DATEPART(YYYY,getdate()) * 10000 + DATEPART(MM,getdate()) * 100 + DATEPART(DD,getdate())
  6059.  
  6060.     -- But never let startdate be > end date
  6061.     IF (@activestartdate > @activeenddate)
  6062.     SELECT @activestartdate=@activeenddate
  6063.  
  6064.     IF (@activestarttimeofday = 0)
  6065.       SELECT @activestarttimeofday = NULL
  6066.     IF (@activeendtimeofday = 0)
  6067.       SELECT @activeendtimeofday = NULL
  6068.     IF (@freqtype <> 0x2) -- OnDemand tasks simply have no schedule in 7.0
  6069.     BEGIN
  6070.       select @schedule_name = formatmessage(20532)
  6071.  
  6072.       EXECUTE @retval = msdb.dbo.sp_add_jobschedule
  6073.         @job_id                 = @job_id,
  6074.         @name                   = @schedule_name,
  6075.         @enabled                = 1,
  6076.         @freq_type              = @freqtype,
  6077.         @freq_interval          = @freqinterval,
  6078.         @freq_subday_type       = @freqsubtype,
  6079.         @freq_subday_interval   = @freqsubinterval,
  6080.         @freq_relative_interval = @freqrelativeinterval,
  6081.         @freq_recurrence_factor = @freqrecurrencefactor,
  6082.         @active_start_date      = @activestartdate,
  6083.         @active_end_date        = @activeenddate,
  6084.         @active_start_time      = @activestarttimeofday,
  6085.         @active_end_time        = @activeendtimeofday
  6086.  
  6087.       IF (@retval <> 0)
  6088.       BEGIN
  6089.         GOTO UNDO
  6090.       END
  6091.     END
  6092.  
  6093.     -- And finally, add the job server
  6094.     EXECUTE @retval = msdb.dbo.sp_add_jobserver @job_id = @job_id, @server_name  = '(local)'
  6095.  
  6096.     IF (@retval <> 0)
  6097.     BEGIN
  6098.       GOTO UNDO
  6099.     END
  6100.  
  6101.   COMMIT TRANSACTION
  6102.  
  6103.   -- If this is an autostart LogReader or Distribution or Merge job, add the [new] '-Continuous' paramter to the command
  6104.   IF (@freqtype = 0x40) AND ((UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS) = 'LOGREADER') OR (UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS) = 'DISTRIBUTION') OR 
  6105.             (UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS) = 'MERGE') OR (UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS) = 'QUEUEREADER'))
  6106.   BEGIN
  6107.     UPDATE msdb.dbo.sysjobsteps
  6108.     SET command = command + ' -Continuous'
  6109.     WHERE (job_id = @job_id)
  6110.       AND ((@failure_detection = 0 and step_id = 1) or (@failure_detection = 1 and step_id = 2))
  6111.   END  
  6112.  
  6113.   -- If this is an autostart job, start it now (for backwards compatibility with 6.x SQLExecutive behaviour)
  6114.   IF (@freqtype = 0x40)
  6115.     EXECUTE msdb.dbo.sp_start_job @job_id = @job_id, @error_flag = 0
  6116.  
  6117.   RETURN(0)
  6118.  
  6119. UNDO:
  6120.     rollback tran sp_MSadd_repl_job
  6121.     commit tran
  6122.     return(1)
  6123.  
  6124. END
  6125. go
  6126.  
  6127. raiserror('Creating procedure sp_MScheck_subscription', 0,1)
  6128. go
  6129.  
  6130. CREATE PROCEDURE sp_MScheck_subscription (
  6131. @publication    sysname,  --     1 Tran, 2 Merge
  6132. @pub_type        int
  6133. )AS
  6134. declare @merge_pubid    uniqueidentifier
  6135. declare @tran_pubid        int
  6136. declare @retcode int
  6137.  
  6138. -- Security check
  6139. exec @retcode = dbo.sp_MSreplcheck_pull @publication = @publication
  6140. if @retcode <> 0 or @@error <> 0
  6141.     return 1
  6142.  
  6143. if @pub_type = 2
  6144. BEGIN
  6145.     if not exists (select * from sysobjects where name = 'sysmergepublications')
  6146.         begin
  6147.             raiserror(20054, 16, -1)
  6148.             return (1)
  6149.         end
  6150.     select @merge_pubid = pubid from sysmergepublications where name=@publication and publisher=@@SERVERNAME and publisher_db=db_name()
  6151.     if @merge_pubid is NULL
  6152.         begin
  6153.             raiserror(20026, 16, -1, @publication)
  6154.             return (1)
  6155.         end
  6156.     if EXISTS (select * from sysmergesubscriptions where pubid=@merge_pubid and subid<>pubid)
  6157.         select 1
  6158.     else 
  6159.         select 0
  6160. END
  6161. else    -- if not merge, it has to be tran level. For other level, a generic error will be returned
  6162. BEGIN
  6163.     if not exists (select * from sysobjects where name='syspublications')
  6164.         begin
  6165.             raiserror(20054, 16, -1)
  6166.             return (1)
  6167.         end
  6168.     select @tran_pubid = pubid from syspublications where name=@publication
  6169.     if @tran_pubid is NULL 
  6170.         begin
  6171.             raiserror(20026, 16, -1, @publication)
  6172.             return (1)
  6173.         end
  6174.     if EXISTS (select * from syssubscriptions where (srvid <> -1) and artid in 
  6175.                        (select artid from sysextendedarticlesview where pubid=@tran_pubid))
  6176.           select 1
  6177.     else
  6178.            select 0
  6179. END
  6180. GO
  6181.  
  6182. exec dbo.sp_MS_marksystemobject sp_MScheck_subscription
  6183. go
  6184. grant execute on dbo.sp_MScheck_subscription to public
  6185. go
  6186.  
  6187. -- system procedure : returns string representing path to shared tools directory for 
  6188. -- the current instance as an output parm; if unable to get path, returns 1
  6189. raiserror(15339,-1,-1,'sp_MSgettools_path')
  6190. GO
  6191. CREATE PROCEDURE dbo.sp_MSgettools_path ( @install_path NVARCHAR(260) OUTPUT )
  6192. AS
  6193. BEGIN
  6194.     
  6195.     DECLARE @retcode INTEGER
  6196.     DECLARE @regkey NVARCHAR(260)
  6197.     DECLARE @len_minorversion tinyint
  6198.  
  6199.     SET NOCOUNT ON 
  6200.     
  6201.     SELECT @len_minorversion = 1 -- assume only 10's digit of minor version is significant
  6202.     SELECT @regkey = 'SOFTWARE\Microsoft\Microsoft SQL Server\' + dbo.fn_MSsharedversion(@len_minorversion) + '\Tools\ClientSetup'
  6203.  
  6204.     EXECUTE @retcode = master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', 
  6205.         @regkey,
  6206.         'SQLPath',
  6207.         @param = @install_path OUTPUT
  6208.  
  6209.     IF ( @retcode <> 0 ) or ( @@ERROR <> 0 ) or ( @install_path IS NULL ) or ( @install_path = '' )
  6210.     BEGIN
  6211.         RETURN (1)
  6212.     END
  6213.  
  6214.     RETURN (0)
  6215.  
  6216. END
  6217. GO
  6218.  
  6219. raiserror('Creating procedure sp_replicationoption', 0,1)
  6220. go
  6221.  
  6222. CREATE PROCEDURE sp_replicationoption (
  6223. @optname        sysname,
  6224. @value            nvarchar(5),
  6225. @security_mode    int = 0,
  6226. @login            sysname = 'sa',
  6227. @password        sysname = NULL,
  6228. @reserved       nvarchar(20) = NULL
  6229. )
  6230. AS
  6231.     DECLARE @optbit bit
  6232.     DECLARE @osql_path nvarchar(260)
  6233.     DECLARE @osql_cmd1 nvarchar (255)
  6234.     DECLARE @osql_cmd_full nvarchar (255)
  6235.     DECLARE @osql_for_nt int
  6236.  
  6237.     DECLARE @install_path nvarchar (255)
  6238.  
  6239.     DECLARE @retcode int
  6240.     DECLARE @undo_install nvarchar(20)
  6241.     DECLARE @no_scripts nvarchar(10)
  6242.     DECLARE @platform_nt binary
  6243.     
  6244.     SELECT @platform_nt = 0x1
  6245.  
  6246.     if    is_srvrolemember('sysadmin') <> 1
  6247.         BEGIN
  6248.             RAISERROR (15232, 14, -1)
  6249.             RETURN (1)
  6250.         END
  6251.     
  6252.     SELECT @no_scripts = 'no_scripts'
  6253.  
  6254.     SELECT @undo_install = 'undo_install'
  6255.  
  6256.     IF db_name() <> 'master'
  6257.     BEGIN
  6258.         RAISERROR(5001, 16,-1)
  6259.         GOTO FAILURE
  6260.     END
  6261.  
  6262.     IF LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('transactional','merge')
  6263.     BEGIN
  6264.         RAISERROR(21014, 16, -1)
  6265.         GOTO FAILURE
  6266.     END
  6267.     IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('true','false')
  6268.     BEGIN
  6269.         RAISERROR(14137,16,-1)
  6270.         GOTO FAILURE
  6271.     END
  6272.     
  6273.     IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) = 'true'
  6274.         SELECT @optbit = 1
  6275.     ELSE
  6276.         SELECT @optbit = 0
  6277.  
  6278.     /*
  6279.     ** Check if the option is set as required already
  6280.     */
  6281.     IF @reserved <> @undo_install AND EXISTS (SELECT * FROM MSreplication_options
  6282.         WHERE    optname  = @optname
  6283.         AND        value = @optbit)
  6284.     BEGIN
  6285.         IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) = 'true'
  6286.             RAISERROR (21015, 10, -1, @optname)        
  6287.         ELSE
  6288.             RAISERROR (21016, 10, -1, @optname)
  6289.         GOTO FAILURE
  6290.     END
  6291.  
  6292.     /* Install replication */
  6293.     IF @optbit = 1
  6294.     BEGIN
  6295.  
  6296.         IF LOWER(@reserved collate SQL_Latin1_General_CP1_CS_AS) = @no_scripts
  6297.             GOTO NO_SCRIPTS
  6298.  
  6299.         -- Set the flag for platform
  6300.         IF (( platform() & @platform_nt = @platform_nt ))
  6301.             SELECT @osql_for_nt = 1
  6302.         ELSE
  6303.             SELECT @osql_for_nt = 0
  6304.  
  6305.         /* 
  6306.         ** Get installation path -- osql client (TOOLS) path
  6307.         */
  6308.         EXECUTE @retcode = master.dbo.sp_MSgettools_path @osql_path OUTPUT
  6309.         IF ( @@ERROR <> 0 ) OR ( @retcode <> 0 ) or ( @osql_path is NULL ) or ( @osql_path = '' )
  6310.         BEGIN
  6311.             GOTO FAILURE       
  6312.         END
  6313.  
  6314.         /* 
  6315.         ** Get installation path -- instance specific (INSTALL) directory
  6316.         */
  6317.         exec @retcode = master.dbo.sp_MSget_setup_paths
  6318.             @sql_path = @install_path output
  6319.         IF @@ERROR<> 0 OR @retcode <> 0 or @install_path is NULL or @install_path=''
  6320.             BEGIN
  6321.                 GOTO FAILURE       
  6322.             END
  6323.  
  6324.         /* 
  6325.         ** Install replcom.sql and repltran.sql
  6326.         */
  6327.         IF @security_mode = 1
  6328.         begin
  6329.             SELECT @osql_cmd1 = '"' + fn_escapecmdshellsymbolsremovequotes(@osql_path) collate database_default + '\binn\osql" -E ' 
  6330.             if serverproperty('instancename') is not null
  6331.                 SELECT @osql_cmd1 = @osql_cmd1 + ' -S"' + fn_escapecmdshellsymbols(@@SERVERNAME) collate database_default + '" '
  6332.         end
  6333.         ELSE
  6334.             -- cannot specify -S w/ -E for local execution, SID does not map
  6335.             SELECT @osql_cmd1 = '"' + fn_escapecmdshellsymbolsremovequotes(@osql_path) collate database_default + '\binn\osql" -U"' + fn_escapecmdshellsymbols(@login) collate database_default + '" -P"' + 
  6336.                 fn_escapecmdshellsymbols(isnull(@password,'')) collate database_default + '" -S"' + fn_escapecmdshellsymbols(@@SERVERNAME) collate database_default + '" '
  6337.  
  6338.         select @osql_cmd1 = @osql_cmd1 + '-l30 -t30 '
  6339.  
  6340.         -- Install replcom.sql 
  6341.         -- Only apply replcom.sql if it was not applied before.
  6342.         -- '-b' option will make osql stop at errors and return error code
  6343.         -- We must use this option.
  6344.         IF NOT EXISTS (SELECT * FROM MSreplication_options
  6345.             WHERE value = 1)
  6346.         BEGIN
  6347.             -- Initialize the Command
  6348.             IF (@osql_for_nt = 1)
  6349.                 SELECT @osql_cmd_full = '" '
  6350.             ELSE
  6351.                 SELECT @osql_cmd_full = ' '
  6352.  
  6353.             SELECT @osql_cmd_full = @osql_cmd_full +
  6354.                 @osql_cmd1 + 
  6355.                 ' -dmaster' +  ' -b ' +
  6356.                 ' -i' + '"' + fn_escapecmdshellsymbolsremovequotes(@install_path) collate database_default + '\install\replcom.sql"' + 
  6357.                 ' -o' + '"' + fn_escapecmdshellsymbolsremovequotes(@install_path) collate database_default + '\install\replcom.out"' 
  6358.  
  6359.             IF (@osql_for_nt = 1)
  6360.                 SELECT @osql_cmd_full = @osql_cmd_full + ' "'
  6361.  
  6362.             EXEC @retcode = master..xp_cmdshell @osql_cmd_full
  6363.             IF @@ERROR<> 0 OR @retcode <> 0
  6364.             BEGIN
  6365.                 RAISERROR (14113, 16, -1, @osql_cmd_full, 'replcom.out')
  6366.                 GOTO UNDO_INSTALL     
  6367.             END
  6368.         END
  6369.  
  6370.         IF LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) = 'transactional'
  6371.         BEGIN
  6372.             -- Install repltran.sql
  6373.             IF (@osql_for_nt = 1)
  6374.                 SELECT @osql_cmd_full = '" '
  6375.             ELSE
  6376.                 SELECT @osql_cmd_full = ' '
  6377.  
  6378.             SELECT @osql_cmd_full = @osql_cmd_full +
  6379.                 @osql_cmd1 + 
  6380.                 ' -dmaster' +  ' -b ' +
  6381.                 ' -i' + '"' + fn_escapecmdshellsymbolsremovequotes(@install_path) collate database_default + '\install\repltran.sql"' + 
  6382.                 ' -o' + '"' + fn_escapecmdshellsymbolsremovequotes(@install_path) collate database_default + '\install\repltran.out"' 
  6383.  
  6384.             IF (@osql_for_nt = 1)
  6385.                 SELECT @osql_cmd_full = @osql_cmd_full + ' "'
  6386.  
  6387.             EXEC @retcode = master..xp_cmdshell @osql_cmd_full
  6388.             IF @@ERROR<> 0 OR @retcode <> 0
  6389.             BEGIN
  6390.                 RAISERROR (14113, 16, -1, @osql_cmd_full, 'repltran.out')
  6391.                 GOTO UNDO_INSTALL     
  6392.             END
  6393.  
  6394.         END
  6395.  
  6396.         IF LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) = 'merge'
  6397.         BEGIN
  6398.             -- Install replmerg.sql 
  6399.             IF (@osql_for_nt = 1)
  6400.                 SELECT @osql_cmd_full = '" '
  6401.             ELSE
  6402.                 SELECT @osql_cmd_full = ' '
  6403.  
  6404.             SELECT @osql_cmd_full = @osql_cmd_full +
  6405.                 @osql_cmd1 + 
  6406.                 ' -dmaster' + ' -b ' +
  6407.                 ' -i' + '"' + fn_escapecmdshellsymbolsremovequotes(@install_path) collate database_default + '\install\replmerg.sql"' + 
  6408.                 ' -o' + '"' + fn_escapecmdshellsymbolsremovequotes(@install_path) collate database_default + '\install\replmerg.out"' 
  6409.             
  6410.             IF (@osql_for_nt = 1)
  6411.                 SELECT @osql_cmd_full = @osql_cmd_full + ' "'
  6412.  
  6413.             EXEC @retcode = master..xp_cmdshell @osql_cmd_full 
  6414.             
  6415.             IF  @@ERROR<> 0 OR @retcode <> 0
  6416.             BEGIN
  6417.                 RAISERROR (14113, 16, -1, @osql_cmd_full, 'replmerg.out')
  6418.                 GOTO UNDO_INSTALL     
  6419.             END
  6420.         END
  6421.  
  6422. NO_SCRIPTS:
  6423.  
  6424.         UPDATE MSreplication_options SET value = @optbit
  6425.             WHERE optname = @optname
  6426.         IF @@ERROR <> 0 
  6427.         BEGIN
  6428.             GOTO UNDO_INSTALL    
  6429.         END
  6430.  
  6431.     END
  6432.     /* Uninstall replication */
  6433.     ELSE
  6434.     BEGIN
  6435.  
  6436.         /* 
  6437.         ** Make sure no distributor installed before dropping 
  6438.         ** replication stored procedures
  6439.         */
  6440.         IF EXISTS (SELECT * FROM master..sysservers
  6441.               WHERE  srvstatus & 8 <> 0)
  6442.         BEGIN
  6443.             RAISERROR (21021, 16, -1)
  6444.             RETURN(1)
  6445.         END
  6446.  
  6447.         UPDATE MSreplication_options SET value = @optbit
  6448.             WHERE optname = @optname
  6449.         IF @@ERROR <> 0 
  6450.         BEGIN
  6451.             GOTO FAILURE
  6452.         END
  6453.  
  6454.         /* 
  6455.         *********** Do not drop replication stored procs anymore.
  6456.  
  6457.         IF LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) = 'transactional'
  6458.         BEGIN
  6459.             if exists (select * from sysobjects
  6460.                 where type = 'P '
  6461.                         and name = 'sp_MSdrop_repltran')
  6462.             begin
  6463.                 exec @retcode = dbo.sp_MSdrop_repltran
  6464.                 if @@ERROR = 0 and @retcode = 0
  6465.                     drop procedure sp_MSdrop_repltran
  6466.             end
  6467.         END
  6468.  
  6469.         IF LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) = 'merge'
  6470.         BEGIN
  6471.             if exists (select * from sysobjects
  6472.                 where type = 'P '
  6473.                         and name = 'sp_MSdrop_replmerg')
  6474.             begin
  6475.                 exec @retcode = dbo.sp_MSdrop_replmerg
  6476.                 if @@ERROR = 0 and @retcode = 0
  6477.                     drop procedure sp_MSdrop_replmerg
  6478.             end
  6479.         END
  6480.  
  6481.         IF NOT EXISTS (SELECT * FROM MSreplication_options
  6482.             WHERE value = 1)
  6483.         BEGIN
  6484.             if exists (select * from sysobjects
  6485.                 where type = 'P '
  6486.                         and name = 'sp_MSdrop_replcom')
  6487.             begin
  6488.                 exec @retcode = dbo.sp_MSdrop_replcom
  6489.                 if @@ERROR = 0 and @retcode = 0
  6490.                     drop procedure sp_MSdrop_replcom
  6491.             end
  6492.         END
  6493.  
  6494.         */
  6495.     END
  6496.  
  6497.     RETURN(0)
  6498.  
  6499. UNDO_INSTALL:
  6500.     /* This is needed to drop the stored procedures that were created. */
  6501.     EXEC dbo.sp_replicationoption @optname =  @optname, 
  6502.         @value = 'false', @reserved = @undo_install
  6503.  
  6504. FAILURE:
  6505.     RETURN(1)
  6506. GO
  6507. exec dbo.sp_MS_marksystemobject sp_replicationoption
  6508. go
  6509. grant execute on dbo.sp_replicationoption to public
  6510.     
  6511.  
  6512. raiserror('Creating procedure sp_helpreplicationoption', 0,1)
  6513. go
  6514.  
  6515. CREATE PROCEDURE sp_helpreplicationoption (
  6516. @optname        sysname = NULL
  6517. )
  6518. AS
  6519.     DECLARE @optbit bit
  6520.     DECLARE @retcode int
  6521.  
  6522.  
  6523.     IF @optname IS NOT NULL AND LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('transactional','merge')
  6524.     BEGIN
  6525.         RAISERROR(21014, 16, -1)
  6526.         GOTO FAILURE
  6527.     END
  6528.     
  6529.     SELECT optname, value, major_version, minor_version, revision 
  6530.         FROM master..MSreplication_options
  6531.         WHERE
  6532.             optname = @optname OR
  6533.             @optname = NULL
  6534.  
  6535.     RETURN(0)
  6536.  
  6537. FAILURE:
  6538.     RETURN(1)
  6539. GO
  6540. exec dbo.sp_MS_marksystemobject sp_helpreplicationoption
  6541. go
  6542. grant execute on dbo.sp_helpreplicationoption to public
  6543.  
  6544. raiserror('Creating procedure sp_MSgetreplnick', 0,1)
  6545. GO
  6546.  
  6547. create procedure sp_MSgetreplnick (
  6548.     @server        sysname = NULL,
  6549.     @db_name    sysname = NULL,
  6550.     @pubid        uniqueidentifier  = NULL,
  6551.     @nickname    int output
  6552.     )
  6553. as
  6554.     declare @srvid             int
  6555.     
  6556.     if @db_name IS NULL
  6557.         select @db_name = db_name()
  6558.  
  6559.     /* Use 0 if the Server name is not passed in since it would be the local server */
  6560.     if @server IS NULL
  6561.         select @srvid = 0
  6562.     else            
  6563.         select @srvid = max(srvid) from master..sysservers where UPPER(srvname) = UPPER(@server) collate database_default
  6564.  
  6565.     if (@pubid IS NOT NULL)
  6566.         begin
  6567.             select @nickname = max(replnickname) from MSmerge_replinfo 
  6568.                 where repid in (select subid from sysmergesubscriptions
  6569.                     where srvid = @srvid and db_name = @db_name and pubid = @pubid)
  6570.         end
  6571.     else
  6572.         begin
  6573.             select @nickname = max(replnickname) from MSmerge_replinfo 
  6574.                 where repid in (select subid from sysmergesubscriptions
  6575.                         where srvid = @srvid and db_name = @db_name)
  6576.         end
  6577. go
  6578.  
  6579. exec dbo.sp_MS_marksystemobject sp_MSgetreplnick
  6580. go
  6581. grant execute on dbo.sp_MSgetreplnick to public
  6582.  
  6583. raiserror('Creating procedure sp_MSreplcheck_publish', 0,1)
  6584. go
  6585.  
  6586. CREATE PROCEDURE sp_MSreplcheck_publish 
  6587. AS
  6588. BEGIN
  6589.     --
  6590.     -- reintroducing the sysadmin check as it is 4 times more efficient
  6591.     -- than is_member call and reduces performance overhead in case 
  6592.     -- the user has sysadmin privileges
  6593.     --
  6594.     if (is_srvrolemember('sysadmin') = 1 or is_member('db_owner') = 1)
  6595.         return 0
  6596.     else
  6597.     BEGIN
  6598.         RAISERROR (21050, 14, -1)
  6599.         RETURN (1)
  6600.     END
  6601. END
  6602. GO
  6603.  
  6604.  
  6605. raiserror('Creating procedure sp_MSlocktable', 0,1)
  6606. go
  6607. CREATE PROCEDURE sp_MSlocktable
  6608. @ownername        sysname,
  6609. @tablename        sysname
  6610. AS
  6611.     declare @retcode            int
  6612.     declare @procname            sysname
  6613.     declare @objid                 int
  6614.     declare @qualified_name        nvarchar(270)
  6615.     select @qualified_name = QUOTENAME(@ownername) + '.' + QUOTENAME(@tablename)
  6616.     select @objid = object_id(@qualified_name)
  6617.     if @objid is NULL
  6618.         select @objid = id from sysobjects where name=@tablename
  6619.     if @objid is null
  6620.         return (1)
  6621.     
  6622.     exec @retcode = dbo.sp_MSrepl_PAL_rolecheck @objid = @objid 
  6623.     if (@retcode <> 0 or @@error <> 0)
  6624.         return 1
  6625.     
  6626.     select @procname = select_proc from sysmergearticles where objid = @objid and select_proc is not NULL
  6627.     exec @retcode = @procname @type = 7
  6628.     IF @@ERROR<>0 or @retcode<>0 RETURN (1)
  6629.  
  6630. --  exec ('select count(*) from ' + @ownername + '.' + @tablename + ' (tablock holdlock) where 1 = 2')
  6631. go
  6632. exec dbo.sp_MS_marksystemobject sp_MSlocktable
  6633. go
  6634. grant execute on dbo.sp_MSlocktable to public
  6635. go
  6636.  
  6637. raiserror('Creating procedure sp_MSenumcolumns', 0,1)
  6638. go
  6639. CREATE PROCEDURE sp_MSenumcolumns
  6640.     @pubid uniqueidentifier,
  6641.     @artid uniqueidentifier
  6642. AS
  6643.     declare @retcode            int
  6644.     declare @procname            sysname
  6645.     
  6646.     select @procname = select_proc from sysmergearticles where pubid = @pubid and artid = @artid
  6647.     exec @retcode = @procname @type =6
  6648.  
  6649. go
  6650. exec dbo.sp_MS_marksystemobject sp_MSenumcolumns
  6651. go
  6652. grant execute on dbo.sp_MSenumcolumns to public
  6653. go
  6654.  
  6655. /*
  6656. ** Get pubid through connection_ID and check permission of this publication
  6657. */
  6658.  
  6659. raiserror('Creating procedure sp_MSsetaccesslist', 0,1)
  6660. go
  6661. CREATE PROCEDURE sp_MSsetaccesslist
  6662. @publication     sysname,
  6663. @publisher         sysname,
  6664. @publisher_db    sysname
  6665. AS
  6666.  
  6667. -- we don't need to do anything here since we are using role based security
  6668.     return 0
  6669. go
  6670. exec dbo.sp_MS_marksystemobject sp_MSsetaccesslist
  6671. go
  6672. grant execute on dbo.sp_MSsetaccesslist to public
  6673. go
  6674.             
  6675. --
  6676. -- Name: sp_MSreplcheck_pull
  6677. --
  6678. -- Description: This proc is called publication PAL security check
  6679. --
  6680. -- Parameter: Refer to the comments in the create procedure statement
  6681. --
  6682. -- Returns: 1 or 0   0 = success
  6683. --
  6684. -- Security: Public procedure  
  6685. --
  6686. raiserror('Creating procedure sp_MSreplcheck_pull', 0,1)
  6687. go
  6688.  
  6689. create procedure sp_MSreplcheck_pull 
  6690. (
  6691.     @publication sysname,
  6692.     @raise_fatal_error bit = 1,
  6693.     @pubid uniqueidentifier = NULL,
  6694.     @given_login sysname = NULL
  6695. )
  6696. as
  6697. begin
  6698.     declare @login sysname
  6699.                 ,@login_time datetime
  6700.  
  6701.     --
  6702.     -- initialize
  6703.     --
  6704.     if (@given_login = N'')
  6705.         select @given_login = null
  6706.     --
  6707.     -- Special processing if explicit login was not provided
  6708.     --
  6709.     if @given_login is null 
  6710.     begin
  6711.         --
  6712.         -- explict login not provided
  6713.         -- sysadmin or db_owner have access
  6714.         --
  6715.         if (is_srvrolemember('sysadmin') = 1 or is_member('db_owner') = 1)
  6716.             return (0)
  6717.         --
  6718.         -- If spid with publication in the cache, return success.
  6719.         --
  6720.         select @login_time = login_time from master..sysprocesses where spid = @@spid
  6721.         if exists (select login_time 
  6722.             from tempdb.dbo.MSpublisher_access 
  6723.             where spid = @@spid 
  6724.                 and login_time = @login_time
  6725.                 and db_id = db_id() 
  6726.                 and publication = @publication)
  6727.         return (0)
  6728.     end
  6729.     --
  6730.     -- Get the current login
  6731.     -- NOTE: why is user_name() not being used
  6732.     --
  6733.     select @login = suser_sname(suser_sid())
  6734.     --
  6735.     -- Special processing if explicit login was provided
  6736.     --
  6737.     if ((@given_login is not null) and (@login <> @given_login))
  6738.     begin
  6739.         --
  6740.         -- To determine whether another login has access to a publication
  6741.         -- requires user to be db_owner in the publishing database
  6742.         --
  6743.         if is_member('db_owner') <> 1
  6744.             return (1)
  6745.         select @login = @given_login
  6746.     end
  6747.     --
  6748.     -- If we have reached here - means - need to get the publication access
  6749.     -- information from distribution db
  6750.     --
  6751.     declare @has_access bit
  6752.                 ,@distribdb sysname
  6753.                 ,@distproc nvarchar (300)
  6754.                 ,@retcode int
  6755.                 ,@dist_rpcname sysname
  6756.                 ,@database sysname
  6757.  
  6758.     --
  6759.     -- initialize RPC information
  6760.     --
  6761.     select @database = db_name()
  6762.     EXEC @retcode = dbo.sp_helpdistributor     @rpcsrvname = @dist_rpcname OUTPUT,
  6763.                                            @distribdb   = @distribdb   OUTPUT
  6764.     IF @retcode <> 0 or @@error <> 0
  6765.     BEGIN
  6766.          RAISERROR (14071, 16, -1)
  6767.          return (1)
  6768.     END
  6769.     IF @retcode <> 0 OR @distribdb IS NULL OR @dist_rpcname IS NULL
  6770.     BEGIN
  6771.         RAISERROR (14071, 16, -1)
  6772.         return(1)
  6773.     END
  6774.     --
  6775.     -- Invoke call on distribution db
  6776.     --
  6777.     SELECT @distproc = RTRIM(@dist_rpcname) + '.' + RTRIM(@distribdb) + '.dbo.sp_MSpublication_access'
  6778.     EXEC @retcode = @distproc
  6779.                 @publisher = @@SERVERNAME,
  6780.                 @publisher_db = @database,
  6781.                 @publication = @publication,
  6782.                 @operation = 'check',
  6783.                 @login = @login,
  6784.                 @has_access = @has_access output
  6785.     IF @@error <> 0 OR @retcode <> 0
  6786.         return (1)
  6787.     --
  6788.     -- Check access information
  6789.     --
  6790.     if @has_access = 0
  6791.     begin
  6792.         -- We don't have access if we reach here, return error
  6793.         IF @raise_fatal_error = 1
  6794.             RAISERROR (21049, 14, -1, @login, @publication)
  6795.         ELSE
  6796.             RAISERROR (21049, 10, -1, @login, @publication)
  6797.         return(1)
  6798.     end
  6799.     --
  6800.     -- If explicit login is being used - do not cache
  6801.     --
  6802.     if (@given_login is not null)
  6803.         return (0)
  6804.     --
  6805.     -- If we are here - means - need to add access information to the cache.
  6806.     -- Clear the cache to keep it small.
  6807.     --
  6808.     exec @retcode = dbo.sp_MSflush_access_cache
  6809.     if @retcode <> 0 or @@error <> 0
  6810.         return (1)
  6811.     --
  6812.     -- insert entry for this publication access
  6813.     --
  6814.     insert tempdb.dbo.MSpublisher_access
  6815.         (spid, db_id, publication, login_time, pubid) values
  6816.         (@@spid, db_id(), @publication, @login_time, @pubid)
  6817.     if @@error <> 0
  6818.         return (1)
  6819.     --
  6820.     -- all done
  6821.     --
  6822.     return (0)
  6823. end
  6824. GO
  6825. exec dbo.sp_MS_marksystemobject sp_MSreplcheck_pull
  6826. go
  6827. grant execute on dbo.sp_MSreplcheck_pull to public
  6828. go
  6829.  
  6830. raiserror('Creating procedure sp_MSreplcheck_connection', 0,1)
  6831. go
  6832.  
  6833. CREATE PROCEDURE sp_MSreplcheck_connection
  6834. @publication sysname = NULL,
  6835. @artid uniqueidentifier = NULL,
  6836. @repid uniqueidentifier = NULL,
  6837. @pubid uniqueidentifier = NULL,
  6838. @objid int                = NULL,
  6839. @tablenick int = NULL,
  6840. @is_init bit = 0
  6841. AS
  6842.     -- sysadmin or db_owner have access
  6843.     if is_member('db_owner') = 1 
  6844.         return 0
  6845.  
  6846.     declare @retcode int
  6847.     declare @cached_id uniqueidentifier
  6848.  
  6849.     -- Need login_time to uniquely identify a connection.
  6850.     declare @login_time datetime
  6851.     select @login_time = login_time from master..sysprocesses where spid = @@spid
  6852.  
  6853.     select @cached_id = pubid from tempdb.dbo.MSpublisher_access where 
  6854.         spid = @@spid and
  6855.         login_time = @login_time
  6856.  
  6857.     -- If spid with publication in the cache, return success.
  6858.     if @cached_id is null
  6859.     begin
  6860.         -- This stored procedure might be called by common sprocs at
  6861.         -- both the publisher and the subscriber by the merge agent
  6862.         -- The merge agent will call this sp with @is_init = 1 before
  6863.         -- any other calls to the publisher. All the other calls will
  6864.         -- set @is_init to 0.
  6865.  
  6866.         -- it is not a problem if the entry is not found in the cache and 
  6867.         -- is_init is set to 0. We should not fail here and instead call
  6868.         -- replcheck_pull to make get the cache entry back.
  6869.         exec @retcode = dbo.sp_MSreplcheck_pull @publication = @publication,
  6870.             @pubid = @pubid
  6871.         if @retcode <> 0 or @@error <> 0
  6872.             begin
  6873.                 return (1)
  6874.             end
  6875.     end
  6876.     else
  6877.     begin
  6878.         if @pubid is not null
  6879.         begin
  6880.             if @pubid <> @cached_id
  6881.             begin
  6882.                 RAISERROR (14126, 11, -1)
  6883.                 return (1)
  6884.             end
  6885.  
  6886.         end
  6887.         else if @tablenick is not null
  6888.         begin
  6889.             if not exists (select * from sysmergearticles where pubid = @cached_id and 
  6890.                 nickname = @tablenick)
  6891.             begin
  6892.                 RAISERROR (14126, 11, -1)
  6893.                 return (1)
  6894.             end
  6895.         end
  6896.         else if @artid is not null
  6897.         begin
  6898.             if not exists (select * from sysmergearticles where pubid = @cached_id and 
  6899.                 artid = @artid)
  6900.             begin
  6901.                 RAISERROR (14126, 11, -1)
  6902.                 return (1)
  6903.             end
  6904.         end
  6905.         else if @objid is not null
  6906.         begin
  6907.             if not exists (select * from sysmergearticles where pubid = @cached_id and 
  6908.                 objid=@objid)
  6909.             begin
  6910.                 RAISERROR (14126, 11, -1)
  6911.                 return (1)
  6912.             end
  6913.         end
  6914.         
  6915.         else if @publication is not null
  6916.         begin
  6917.             if not exists (select * from sysmergepublications where pubid = @cached_id and 
  6918.                 name = @publication)
  6919.             begin
  6920.                 RAISERROR (14126, 11, -1)
  6921.                 return (1)
  6922.             end
  6923.         end
  6924.         else if @repid is not null
  6925.         begin
  6926.             if not exists (select * from sysmergesubscriptions where pubid = @cached_id and 
  6927.                 subid = @repid)
  6928.             begin
  6929.                 RAISERROR (14126, 11, -1)
  6930.                 return (1)
  6931.             end
  6932.         end
  6933.     end
  6934. GO
  6935. exec dbo.sp_MS_marksystemobject sp_MSreplcheck_connection
  6936. go
  6937. grant execute on dbo.sp_MSreplcheck_connection to public
  6938. go
  6939.  
  6940. raiserror('Creating procedure sp_MSrepl_PAL_rolecheck', 0,1)
  6941. go
  6942. CREATE PROCEDURE sp_MSrepl_PAL_rolecheck
  6943. @publication sysname = NULL,
  6944. @artid uniqueidentifier = NULL,
  6945. @repid uniqueidentifier = NULL,
  6946. @pubid uniqueidentifier = NULL,
  6947. @objid int                = NULL,
  6948. @tablenick int = NULL
  6949. AS
  6950.     -- sysadmin or db_owner have access
  6951.     if is_member('db_owner') = 1 
  6952.         return 0
  6953.  
  6954.     if (@pubid is not NULL)
  6955.     begin
  6956.         if (1 <> {fn ISPALUSER(@pubid)})
  6957.         begin
  6958.             RAISERROR (14126, 11, -1)
  6959.             return (1)
  6960.         end
  6961.     end
  6962.     else if (@publication is not NULL)
  6963.     begin
  6964.         if not exists (select * from dbo.sysmergepublications where name = @publication and (1 = {fn ISPALUSER(pubid)}))
  6965.         begin
  6966.             RAISERROR (14126, 11, -1)
  6967.             return (1)
  6968.         end
  6969.     end
  6970.     else if (@artid is not NULL)
  6971.     begin
  6972.         if not exists (select * from dbo.sysmergearticles where artid = @artid and (1 = {fn ISPALUSER(pubid)}))
  6973.         begin
  6974.             RAISERROR (14126, 11, -1)
  6975.             return (1)
  6976.         end
  6977.     end
  6978.     else if (@repid is not NULL)
  6979.     begin
  6980.         if not exists (select * from dbo.sysmergesubscriptions where subid = @repid and (1 = {fn ISPALUSER(pubid)}))
  6981.         begin
  6982.             RAISERROR (14126, 11, -1)
  6983.             return (1)
  6984.         end
  6985.     end
  6986.     else if ((@tablenick is not NULL) and (@tablenick <> 0))
  6987.     begin
  6988.         if not exists (select * from dbo.sysmergearticles where nickname = @tablenick and (1 = {fn ISPALUSER(pubid)}))
  6989.         begin
  6990.             RAISERROR (14126, 11, -1)
  6991.             return (1)
  6992.         end
  6993.     end
  6994.     else if (@objid is not NULL)
  6995.     begin
  6996.         if not exists (select * from dbo.sysmergearticles where objid = @objid and (1 = {fn ISPALUSER(pubid)}))
  6997.         begin
  6998.             RAISERROR (14126, 11, -1)
  6999.             return (1)
  7000.         end
  7001.     end
  7002.     else if not exists(select * from dbo.sysmergepublications where (1 = {fn ISPALUSER(pubid)}))
  7003.     begin
  7004.         RAISERROR (14126, 11, -1)
  7005.         return (1)
  7006.     end
  7007.  
  7008.     return 0
  7009. GO
  7010. exec dbo.sp_MS_marksystemobject sp_MSrepl_PAL_rolecheck
  7011. go
  7012. grant execute on dbo.sp_MSrepl_PAL_rolecheck to public
  7013. go
  7014.  
  7015.  
  7016. raiserror('Creating procedure sp_MSreplcheck_qv', 0, 1)
  7017. GO
  7018.  
  7019. create procedure sp_MSreplcheck_qv
  7020. as
  7021. begin
  7022.  
  7023.     set nocount on 
  7024.         
  7025.     declare @qv_replication varchar(10)
  7026.     declare @qv_engine varchar(10)
  7027.     declare @qv_value_replication integer
  7028.     declare @qv_value_engine integer
  7029.  
  7030.     select @qv_replication = '2745196162', @qv_engine = '845129433'
  7031.  
  7032.     exec @qv_value_replication = master.dbo.sp_MSinstance_qv @qv_replication     
  7033.     if @@ERROR <> 0 
  7034.         select @qv_value_replication = 1
  7035.  
  7036.     exec @qv_value_engine = master.dbo.sp_MSinstance_qv @qv_engine
  7037.     if @@ERROR <> 0
  7038.         select @qv_value_engine = 1
  7039.  
  7040.     -- magic number 1 assumes least common setting on all failure states
  7041.     select isnull( @qv_value_replication, 1 ) as VALUE_REPLICATION, isnull( @qv_value_engine, 1 ) as VALUE_ENGINE
  7042.  
  7043.  
  7044. end
  7045. go
  7046.  
  7047. exec dbo.sp_MS_marksystemobject sp_MSreplcheck_qv
  7048. go    
  7049.  
  7050. grant execute on dbo.sp_MSreplcheck_qv to public
  7051. go
  7052.  
  7053. raiserror('Creating procedure sp_reinitmergepullsubscription', 0, 1)
  7054. GO
  7055.  
  7056. create procedure sp_reinitmergepullsubscription
  7057.     @publisher        sysname  = 'all',
  7058.     @publisher_db    sysname  = 'all',
  7059.     @publication    sysname  = 'all',
  7060.     @upload_first    nvarchar(5) = 'FALSE'
  7061. AS
  7062.     declare @schemaversion            int
  7063.     declare @schematype                smallint
  7064.     declare @schemaguid                uniqueidentifier
  7065.     declare @pubname                sysname
  7066.     declare @publisher_name            sysname
  7067.     declare @retcode                int
  7068.     declare @pubdb                    sysname
  7069.     declare @pubid                    uniqueidentifier
  7070.     declare @subid                    uniqueidentifier
  7071.     declare @artid                    uniqueidentifier
  7072.  
  7073.     
  7074.     /*
  7075.     ** Security check - Need to be a dbo to call this proc
  7076.     */
  7077.     exec @retcode = dbo.sp_MSreplcheck_subscribe
  7078.     if @@error<>0 or @retcode<>0
  7079.         return (1)
  7080.     
  7081.     /*
  7082.     ** Replace 'all' with '%'
  7083.     */
  7084.     set nocount on
  7085.     if LOWER(@publication) = 'all'
  7086.         SELECT @publication = '%'
  7087.  
  7088.     if LOWER(@publisher) = 'all'
  7089.         SELECT @publisher = '%'
  7090.  
  7091.     if LOWER(@publisher_db) = 'all'
  7092.         SELECT @publisher_db = '%'
  7093.     select @retcode = 0
  7094.     /*
  7095.     ** At subscriber side, we need to qualify the publication with server name and database name
  7096.     */
  7097.     IF NOT EXISTS (SELECT * FROM sysmergepublications WHERE name LIKE @publication 
  7098.         and ((@publisher = N'%') or (UPPER(publisher) = UPPER(@publisher))) 
  7099.         and ((@publisher_db = N'%') or (publisher_db = @publisher_db)) )
  7100.         
  7101.         BEGIN
  7102.         IF @publication = '%'
  7103.                 RAISERROR (14008, 11, -1)
  7104.         ELSE
  7105.                 RAISERROR (20026, 11, -1, @publication)
  7106.         RETURN (1)
  7107.         END
  7108.  
  7109.     if LOWER(@upload_first collate SQL_Latin1_General_CP1_CS_AS) not in ('true', 'false')
  7110.     begin
  7111.         raiserror(14148, 16, -1, '@upload_first')
  7112.         return (1)
  7113.     end
  7114.     Declare SYN_CUR CURSOR LOCAL FAST_FORWARD FOR 
  7115.         select subs.subid, pubs.name, pubs.publisher, pubs.publisher_db
  7116.             from sysmergepublications pubs, sysmergesubscriptions subs
  7117.                 where pubs.name LIKE  @publication
  7118.                     AND ((@publisher = '%') OR (UPPER(pubs.publisher) = UPPER(@publisher)))
  7119.                                         AND ((@publisher_db = N'%') OR (pubs.publisher_db = @publisher_db))
  7120.                     AND pubs.pubid=subs.pubid
  7121.                     AND subs.pubid<>subs.subid
  7122.     FOR READ ONLY
  7123.     open SYN_CUR
  7124.     fetch SYN_CUR into @subid, @pubname, @publisher_name, @pubdb
  7125.     while (@@fetch_status<>-1)
  7126.     BEGIN    
  7127.         
  7128.         -- do not update schemaversion if the initial snapshot has never been applied.
  7129.         update MSmerge_replinfo set schemaversion=-1, recgen = NULL, recguid=NULL, 
  7130.             sentgen=NULL, sentguid = NULL where repid=@subid and schemaversion is not null
  7131.  
  7132.         if (@@rowcount <> 0)
  7133.         begin
  7134.             if LOWER(@upload_first collate SQL_Latin1_General_CP1_CS_AS)='true'
  7135.                 update sysmergesubscriptions set status=5 where subid=@subid
  7136.             else
  7137.                 exec @retcode=sp_MSCleanupForPullReinit @publication=@pubname,
  7138.                                               @publisher=@publisher_name,
  7139.                                               @publisher_db=@pubdb
  7140.             if @retcode<>0 or @@ERROR<>0
  7141.             begin
  7142.                 return (1)
  7143.             end
  7144.         end
  7145.  
  7146.         fetch next from SYN_CUR into @subid, @pubname, @publisher_name, @pubdb    
  7147.             -- so that it won't be treated as a new susbscription    
  7148.     END
  7149.     close SYN_CUR
  7150.     deallocate SYN_CUR
  7151.     -- Forget that publisher ever sent us any generations.  They must be resent.
  7152.     -- Publication cleanup will remove the genhistory rows.
  7153.  
  7154.     if @publication = '%'
  7155.         -- get them all
  7156.         update MSmerge_replinfo set recgen = NULL, recguid=NULL, sentgen=NULL, sentguid = NULL
  7157.     else
  7158.         begin
  7159.         select @pubid = pubid from sysmergepublications where name = @publication
  7160.         update MSmerge_replinfo set recgen = NULL, recguid=NULL, sentgen=NULL, sentguid = NULL
  7161.             where repid in (select subid from sysmergesubscriptions where pubid = @pubid)
  7162.         end
  7163. GO
  7164.  
  7165. exec dbo.sp_MS_marksystemobject sp_reinitmergepullsubscription
  7166. go    
  7167. grant execute on dbo.sp_reinitmergepullsubscription to public
  7168. go
  7169. raiserror('Creating procedure sp_MSreplcheck_subscribe', 0,1)
  7170. go
  7171.  
  7172. CREATE PROCEDURE sp_MSreplcheck_subscribe
  7173. AS
  7174. BEGIN
  7175.     --
  7176.     -- reintroducing the sysadmin check as it is 4 times more efficient
  7177.     -- than is_member call and reduces performance overhead in case 
  7178.     -- the user has sysadmin privileges
  7179.     --
  7180.     if (is_srvrolemember('sysadmin') = 1 or is_member('db_owner') = 1)
  7181.         return 0
  7182.     else
  7183.     BEGIN
  7184.         RAISERROR (21050, 14, -1)
  7185.         RETURN (1)
  7186.     END
  7187. END
  7188. GO
  7189.  
  7190. raiserror('Creating procedure sp_MSreplicationcompatlevel', 0,1)
  7191. GO
  7192. create procedure sp_MSreplicationcompatlevel
  7193. @dbname             sysname,
  7194. @cmptlevel            float(8)
  7195. As
  7196.     declare        @is_distdb    smallint
  7197.  
  7198.     select @is_distdb = 0
  7199.  
  7200.     IF EXISTS (select * from msdb..sysobjects where name='MSdistributiondbs')
  7201.         begin
  7202.             IF EXISTS (SELECT * FROM msdb..MSdistributiondbs where name=@dbname)
  7203.                 select @is_distdb = 1
  7204.         end
  7205.         
  7206.     /*
  7207.     ** Parameter check
  7208.     ** @dbname
  7209.     */
  7210.     IF NOT EXISTS (SELECT * FROM master.dbo.sysdatabases WHERE
  7211.         name = @dbname collate database_default)
  7212.     BEGIN
  7213.         RAISERROR(15010, 16, -1, @dbname)
  7214.         RETURN(2)
  7215.     END
  7216.  
  7217.     select @dbname = QUOTENAME(@dbname)
  7218.  
  7219.     /*
  7220.     ** Parameter check. NOTE
  7221.     ** @cmptlevel
  7222.     */
  7223.     IF @cmptlevel<6.0
  7224.     BEGIN
  7225.         RAISERROR(20060,16,-1)
  7226.         RETURN(2)
  7227.     END
  7228.  
  7229.     /*
  7230.     ** If cmptlevel is lower than 7.0, special attention should be paid. 
  7231.     ** If current database is a distribution database or is involed in merge
  7232.     ** replication, then it can not be set to a level lower than 7.0.
  7233.     */
  7234.     
  7235.     create table #tmp (any_merge smallint NOT NULL)
  7236.     insert into #tmp exec ('select count(*) from ' + @dbname + '..sysobjects where name=' + '''sysmergesubscriptions''' )
  7237.     if (exists(select any_merge from #tmp where any_merge>0) OR @is_distdb = 1) 
  7238.                 AND (@cmptlevel<7.0) 
  7239.         begin
  7240.             drop table #tmp
  7241.             return 1
  7242.         end
  7243.     else 
  7244.         begin
  7245.             drop table #tmp
  7246.             return 0
  7247.         end
  7248. go
  7249.  
  7250. exec dbo.sp_MS_marksystemobject sp_MSreplicationcompatlevel
  7251. go
  7252.  
  7253.  
  7254. raiserror('Creating procedure sp_MShelp_identity_property', 0,1)
  7255. GO
  7256.  
  7257. create procedure sp_MShelp_identity_property
  7258.             @tablename    sysname,
  7259.             @ownername    sysname = NULL
  7260. AS
  7261. declare @qualified_name        nvarchar(270)
  7262. declare @objid                int
  7263. declare @retcode            int
  7264. declare @proc                nvarchar(300)
  7265. declare @distributor        sysname
  7266. declare @distribdb            sysname
  7267. declare @publisher            sysname
  7268. declare @publisherdb        sysname
  7269. declare @pub_range            bigint
  7270. declare @sub_range            bigint
  7271. declare @threshold            int
  7272. declare @artid                int
  7273. declare @next_seed            bigint
  7274. declare @current_max        bigint
  7275. declare @replicated_already    bit
  7276. declare @auto_identity_support int
  7277. declare @identity_incr        int 
  7278. declare    @current_identity    bigint
  7279. declare @max_identity        bigint    
  7280. declare @xprec                int
  7281. declare @xtype                int
  7282. declare @republishing        bit
  7283. declare @length                int
  7284.  
  7285. select @replicated_already = 0
  7286. select @auto_identity_support = NULL
  7287.  
  7288. select @republishing = 0
  7289.  
  7290. select @pub_range    = NULL
  7291. select @sub_range    = NULL
  7292. select @threshold    = NULL
  7293. select @next_seed    = NULL
  7294. select @current_max    = NULL
  7295.  
  7296. if @ownername is not NULL
  7297. begin
  7298.     select @qualified_name = QUOTENAME(@ownername) + '.' + QUOTENAME(@tablename)
  7299.     select @objid = object_id(@qualified_name)
  7300. end
  7301. else
  7302. begin
  7303.     select @qualified_name = QUOTENAME(@tablename)
  7304.     select @objid = id from sysobjects where name=@tablename
  7305. end
  7306. if @objid is NULL
  7307. begin
  7308.     raiserror(14027, 16, -1, @tablename)
  7309.     return (1)
  7310. end
  7311.  
  7312. if OBJECTPROPERTY(@objid, 'tablehasidentity') <> 1
  7313.     begin
  7314.         raiserror(21194, 16, -1)
  7315.         return (1)
  7316.     end
  7317.  
  7318. select @xtype=xtype, @xprec=xprec, @length=length from syscolumns where id=@objid and columnproperty(id, name, 'IsIdentity')=1
  7319.  
  7320. select @max_identity = case @xtype 
  7321.                      when 52 then power((convert(bigint,2)), 8*2 -1) - 1 --smallint 
  7322.                      when 48 then power((convert(bigint,2)), 8 - 1) - 1          --tinyint
  7323.                      when 56 then power((convert(bigint,2)), 8*4 - 1) - 1          --int
  7324.                      when 127 then power((convert(bigint,2)), 62) -1 + power((convert(bigint,2)), 62)          --bigint
  7325.                         else power((convert(bigint,2)), 62) - 1 + power((convert(bigint,2)), 62)               --bigint;.
  7326.                     end
  7327.  
  7328. if (@xtype=108 or @xtype=106) and @xprec<18
  7329.     select @max_identity = power((convert(bigint,10)), (@xprec+1)) - 1
  7330.  
  7331. select @identity_incr = IDENT_INCR(@qualified_name)
  7332. select @current_identity =  ident_current(@qualified_name)
  7333.  
  7334. if exists (select * from sysobjects where name='sysmergearticles')
  7335.     begin
  7336.         if exists (select * from sysmergearticles where objid=@objid)
  7337.             begin
  7338.                 select @replicated_already = 1
  7339.                 select @auto_identity_support = identity_support from sysmergearticles where objid=@objid
  7340.                 if not exists (select * from sysmergearticles where objid=@objid and pubid in
  7341.                     (select pubid from sysmergepublications where publisher_db=db_name() 
  7342.                         and LOWER(publisher)=LOWER(@@SERVERNAME)))
  7343.                     select @republishing = 1
  7344.             end
  7345.     end    
  7346.  
  7347. if exists (select * from sysobjects where name='sysarticles')
  7348.     begin
  7349.         if exists (select * from sysarticles where objid=@objid)
  7350.             begin
  7351.                 select @replicated_already = 1
  7352.                 select @artid = artid from sysarticles where objid=@objid
  7353.                 select @auto_identity_support = identity_support from sysarticleupdates where artid=@artid
  7354.             end
  7355.     end
  7356.  
  7357. if @auto_identity_support is NOT NULL and @auto_identity_support=1
  7358. begin
  7359.     if @republishing = 0
  7360.     begin
  7361.         select @pub_range    = 0
  7362.         select @sub_range    = 0
  7363.         select @threshold    = 0
  7364.         select @next_seed    = 0
  7365.         select @current_max    = 0
  7366.         select @publisher=@@SERVERNAME
  7367.         select @publisherdb=db_name()
  7368.  
  7369.         EXEC @retcode = dbo.sp_helpdistributor     @rpcsrvname = @distributor OUTPUT,
  7370.             @distribdb   = @distribdb   OUTPUT
  7371.         IF @@error <> 0 OR @retcode <> 0
  7372.             RETURN (1)
  7373.  
  7374.         IF @distribdb is null
  7375.             BEGIN
  7376.                 RAISERROR (14071, 16, -1)
  7377.                 RETURN (1)
  7378.             END
  7379.                                      
  7380.         SELECT @proc = RTRIM(@distributor) + '.' + RTRIM(@distribdb) + '.dbo.sp_MScheck_pub_identity'
  7381.         exec @retcode = @proc     @publisher=@publisher, 
  7382.                         @publisher_db=@publisherdb,  
  7383.                         @tablename=@tablename,
  7384.                         @current_max=@current_max OUTPUT,
  7385.                         @pub_range=@pub_range OUTPUT,
  7386.                         @range = @sub_range OUTPUT,
  7387.                         @threshold=@threshold OUTPUT,
  7388.                         @next_seed = @next_seed OUTPUT
  7389.         if @retcode<>0 or @@ERROR<>0
  7390.             return (1)
  7391.  
  7392.         -- Tran pub range is not stored at the distributor
  7393.         if @pub_range = 0
  7394.         begin
  7395.             if object_id('MSpub_identity_range') is not null
  7396.             begin
  7397.                 select @pub_range = pub_range from MSpub_identity_range where
  7398.                     objid = @objid 
  7399.             end
  7400.         end
  7401.     end
  7402.     else
  7403.     begin
  7404.         select @next_seed=next_seed, @max_identity=max_identity, @pub_range=(max_identity-next_seed)*2/10, 
  7405.                 @sub_range=(max_identity-next_seed)/10,
  7406.                 @threshold=80 from MSrepl_identity_range where objid=@objid
  7407.     end
  7408. end
  7409. SELECT 'replicated' = @replicated_already, 
  7410.        'auto_identity_support' = @auto_identity_support, 
  7411.        'identity_incremental' = @identity_incr, 
  7412.        'current_identity' = @current_identity,
  7413.        'next_starting_seed' = @next_seed, 
  7414.        'max_identity' = @max_identity, 
  7415.        'publisher_range' = ABS(@pub_range), 
  7416.        'subscriber_range' = ABS(@sub_range), 
  7417.        'threshold' = @threshold,
  7418.        'in_repulishing' = @republishing
  7419. GO
  7420. exec dbo.sp_MS_marksystemobject sp_MShelp_identity_property
  7421. go
  7422. grant execute on dbo.sp_MShelp_identity_property to public
  7423. GO
  7424.  
  7425. raiserror('Creating procedure sp_MSgenreplnickname', 0,1)
  7426. GO
  7427.  
  7428. create procedure sp_MSgenreplnickname
  7429.             @srcguid    uniqueidentifier,    /* Source Guid */
  7430.             @repnick    int    output    /* nickname */
  7431.     as
  7432.     declare @binguid binary(16)
  7433.     declare    @nickname        int
  7434.     set @binguid = convert(binary(16), @srcguid)
  7435.     select @nickname = convert(int, convert(binary(4),substring( convert(nchar(8),@binguid), 1, 2)))
  7436.     while exists (select replnickname from MSmerge_replinfo where replnickname = @nickname) or
  7437.             (@nickname > 0 and @nickname <= 256)
  7438.     begin
  7439.         select @nickname = @nickname + 1
  7440.     end
  7441.     select @repnick = @nickname
  7442. go
  7443.  
  7444. exec dbo.sp_MS_marksystemobject sp_MSgenreplnickname
  7445. go
  7446. grant execute on dbo.sp_MSgenreplnickname to public
  7447.  
  7448. raiserror('Creating procedure sp_MSmergesubscribedb', 0,1)
  7449. GO
  7450.  
  7451. CREATE PROCEDURE sp_MSmergesubscribedb(
  7452.     @value sysname
  7453.     ) AS
  7454.  
  7455.     SET NOCOUNT ON
  7456.  
  7457.     /*
  7458.     ** Declarations.
  7459.     */
  7460.     declare @retcode                 int
  7461.     
  7462.  
  7463.     /*
  7464.     ** Security Check
  7465.     */
  7466.  
  7467.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  7468.     IF @@ERROR <> 0 or @retcode <> 0
  7469.         RETURN(1)
  7470.  
  7471.  
  7472.     /*
  7473.     ** Initialization
  7474.     */
  7475.  
  7476.  
  7477.     /*
  7478.     ** Parameter check
  7479.     ** @value
  7480.     */
  7481.     IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('true','false')
  7482.     BEGIN
  7483.       RAISERROR(14137,16,-1)
  7484.       RETURN(1)
  7485.     END
  7486.  
  7487.     IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) = 'true'
  7488.         BEGIN        
  7489.             execute @retcode = dbo.sp_MScreate_mergesystables
  7490.             if @@ERROR <> 0 or @retcode <> 0
  7491.                 begin
  7492.                     return (1)
  7493.                 end
  7494.         END
  7495.     
  7496.     -- We assume we will do nothing about disabling a subscriber
  7497.     
  7498. GO
  7499.  
  7500. exec dbo.sp_MS_marksystemobject sp_MSmergesubscribedb
  7501. go
  7502.  
  7503. grant execute on dbo.sp_MSmergesubscribedb to public
  7504. go 
  7505.  
  7506. raiserror('Creating procedure sp_MSenumallsubscriptions', 0,1)
  7507. go
  7508.  
  7509. CREATE PROCEDURE sp_MSenumallsubscriptions(
  7510. @subscription_type    nvarchar(5) = 'push', 
  7511. @subscriber_db        sysname='%'
  7512. )AS
  7513.  
  7514.     set nocount on
  7515.     declare @current_db        sysname
  7516.     declare @retcode        int
  7517.     declare @proc            nvarchar(200)
  7518.     declare @db_status        int
  7519.  
  7520.     create table #MSenumallsubscriptions (
  7521.                         publisher            sysname collate database_default not null,
  7522.                         publisher_db        sysname collate database_default not null,
  7523.                         publication            sysname collate database_default null,
  7524.                         replication_type    int not NULL,
  7525.                         subscription_type    int not NULL,
  7526.                         last_updated        datetime null,
  7527.                         subscriber_db        sysname collate database_default not null,
  7528.                         update_mode            smallint null,
  7529.                         last_sync_status    int null,
  7530.                         last_sync_summary    sysname collate database_default null,
  7531.                         last_sync_time        datetime null
  7532.                         )
  7533.  
  7534.     declare #cur_db cursor local FAST_FORWARD FOR select DISTINCT name, status
  7535.         FROM master.dbo.sysdatabases where ((@subscriber_db = N'%' collate database_default) or (name = @subscriber_db collate database_default)) and
  7536.             has_dbaccess(name) = 1
  7537.     open #cur_db
  7538.     fetch #cur_db into @current_db, @db_status
  7539.     while (@@fetch_status <> -1)
  7540.     begin
  7541.         /*
  7542.          * we only return subscriptions in db which is not in loading (0x20), suspect(0x100),
  7543.          * offline(0x200), in recovering(0x80), shutdown(0x40000), not recovered(0x40)
  7544.          */
  7545.         if (@db_status & 0x403e0) = 0
  7546.             begin
  7547.                 select @proc = QUOTENAME(@current_db) + '.' + 'dbo.sp_MSenumsubscriptions ' 
  7548.                 insert into #MSenumallsubscriptions exec @retcode = @proc  @subscription_type
  7549.                 if @@ERROR<>0 or @retcode<>0
  7550.                     begin
  7551.                         close #cur_db
  7552.                         deallocate #cur_db
  7553.                         return (1)
  7554.                     end
  7555.             end
  7556.         fetch next from #cur_db into @current_db, @db_status
  7557.     end
  7558.     select  distinct 'publisher'                = publisher,
  7559.             'publishing database'    = publisher_db,
  7560.             'publication'            = publication,
  7561.             'replication type'        = replication_type,
  7562.             'subscription type'     = subscription_type,
  7563.             'last updating time'    = convert(nvarchar(12), last_updated, 112) + 
  7564.                                           substring(convert(nvarchar(24), last_updated, 121), 11,13),
  7565.             'subscribing database'  = subscriber_db,
  7566.             'update_mode'           = update_mode,
  7567.             'last sync status'        = last_sync_status,
  7568.             'last sync summary'        = last_sync_summary,
  7569.             'last sync time'        = convert(nvarchar(12), last_sync_time, 112) + 
  7570.                 substring(convert(nvarchar(24), last_sync_time, 121), 11,13)
  7571.     from #MSenumallsubscriptions
  7572.     --drop table #MSenumallsubscriptions
  7573.     close #cur_db
  7574.     deallocate #cur_db
  7575.     return (0)
  7576. Go
  7577. grant execute on dbo.sp_MSenumallsubscriptions to public
  7578. go 
  7579. exec dbo.sp_MS_marksystemobject sp_MSenumallsubscriptions
  7580. GO
  7581.  
  7582. raiserror('Creating procedure sp_MSenumsubscriptions', 0,1)
  7583. go
  7584.  
  7585. CREATE PROCEDURE sp_MSenumsubscriptions(
  7586. @subscription_type    nvarchar(5) = 'push',
  7587. @publisher        sysname = '%',
  7588. @publisher_db     sysname = '%'
  7589. )AS
  7590.  
  7591.     set nocount on
  7592.     declare @dbname        sysname
  7593.     declare @category     int
  7594.     declare @proc            nvarchar(200)
  7595.     declare @retcode    int
  7596.     declare @cur_db        sysname
  7597.     declare @type_value    int
  7598.  
  7599.     select @type_value = 100
  7600.     
  7601.     if LOWER(@subscription_type collate SQL_Latin1_General_CP1_CS_AS)='push'
  7602.         select @type_value = 0
  7603.     else
  7604.         if LOWER(@subscription_type collate SQL_Latin1_General_CP1_CS_AS)='pull'
  7605.             select @type_value = 1
  7606.         else
  7607.             if LOWER(@subscription_type collate SQL_Latin1_General_CP1_CS_AS)='both'
  7608.                 select @type_value = 2
  7609.  
  7610.     select @cur_db = db_name()
  7611.     
  7612.     create table #MSenumpushsubscriptions (
  7613.                         publisher            sysname collate database_default not null,
  7614.                         publisher_db        sysname collate database_default not null,
  7615.                         publication            sysname collate database_default null,
  7616.                         replication_type    int not NULL,
  7617.                         subscription_type    int not NULL,
  7618.                         last_updated        datetime null,
  7619.                         subscriber_db        sysname collate database_default not null,
  7620.                         update_mode            smallint null,
  7621.                         last_sync_status    int null,
  7622.                         last_sync_summary    sysname collate database_default null,
  7623.                         last_sync_time        datetime null
  7624.                         )
  7625.  
  7626.     if exists (select * from sysobjects where name='sysmergesubscriptions')
  7627.     begin
  7628.         -- return all subscriptions that this database is a subscriber to
  7629.         -- suppress all subscriptions that originate from this database.
  7630.         insert into #MSenumpushsubscriptions select p.publisher, p.publisher_db, p.name, 2, 
  7631.             s.subscription_type, s.last_sync_date, s.db_name, 
  7632.             NULL, s.last_sync_status, s.last_sync_summary, s.last_sync_date
  7633.             from sysmergepublications p, sysmergesubscriptions s
  7634.             where p.pubid = s.pubid 
  7635.             and (s.subscription_type=@type_value OR @type_value=2) 
  7636.             and s.pubid <> s.subid 
  7637.             and ((@publisher = N'%') or (p.publisher = @publisher))
  7638.                and ((@publisher_db = N'%') or ( p.publisher_db = @publisher_db))
  7639.             and s.db_name = @cur_db
  7640.             and p.pubid not in 
  7641.                 (select pubid from sysmergepublications pubs where 
  7642.                     lower(pubs.publisher) = LOWER(@@servername) AND
  7643.                     pubs.publisher_db = @cur_db)
  7644.     end
  7645.  
  7646.     if exists (select * from sysobjects where name='MSreplication_subscriptions')
  7647.     begin
  7648.         if  exists (select * from sysobjects where name='MSsubscription_properties') and
  7649.             exists (select * from sysobjects where name='MSsubscription_agents ') 
  7650.         begin
  7651.             -- update_mode in MSreplication_subscriptions table is not reliable.
  7652.             insert into #MSenumpushsubscriptions select s.publisher, s.publisher_db, s.publication,
  7653.                 case isnull(p.publication_type,0) when 0 then 0 else 1 end,
  7654.                 s.subscription_type,
  7655.                 s.time, @cur_db, 
  7656.                 -- NOTE: For Queued case: we will always return 2/3 for the 4/5 case
  7657.                 -- since we overload update_mode based on queue_type
  7658.                 case when isnull(a.update_mode,0) = 4 then 2
  7659.                 when isnull(a.update_mode,0) = 5 then 3
  7660.                 else isnull(a.update_mode,0)
  7661.                 end,
  7662.                 a.last_sync_status,
  7663.                 a.last_sync_summary,
  7664.                 a.last_sync_time
  7665.                 from MSreplication_subscriptions s with (NOLOCK) 
  7666.                 left outer join MSsubscription_agents a with (NOLOCK) 
  7667.                     on (UPPER(s.publisher) = UPPER(a.publisher) and 
  7668.                         s.publisher_db = a.publisher_db and 
  7669.                         ((s.publication = a.publication and 
  7670.                         s.independent_agent = 1 and
  7671.                         a.publication <> N'ALL') or
  7672.                         (a.publication = N'ALL' and s.independent_agent = 0)) and
  7673.                         s.subscription_type = a.subscription_type)
  7674.                 left outer join MSsubscription_properties p with (NOLOCK)
  7675.                     on (UPPER(s.publisher) = UPPER(p.publisher) and 
  7676.                         s.publisher_db = p.publisher_db and 
  7677.                         s.publication = p.publication and
  7678.                         -- don't use property table for push. 
  7679.                         s.subscription_type <> 0) 
  7680.                 where
  7681.                     ((@publisher = N'%') OR (UPPER(s.publisher) = UPPER(@publisher))) AND
  7682.                     ((@publisher_db = N'%') or ( s.publisher_db = @publisher_db)) and
  7683.                     ((s.subscription_type = 0 and @type_value = 0) or
  7684.                     -- For pull, return both pull and anonymous
  7685.                     (s.subscription_type <> 0 and @type_value = 1) or
  7686.                     @type_value = 2) 
  7687.         end
  7688.         -- Property table does not exists.
  7689.         else if exists (select * from sysobjects where name='MSsubscription_agents ') 
  7690.         begin
  7691.             -- update_mode in MSreplication_subscriptions table is not reliable.
  7692.             insert into #MSenumpushsubscriptions select s.publisher, s.publisher_db, s.publication,
  7693.                 -- Property table does not exists. Say transactional.
  7694.                 0,
  7695.                 s.subscription_type,
  7696.                 s.time, @cur_db, 
  7697.                 -- NOTE: For Queued case: we will always return 2/3 for the 4/5 case
  7698.                 -- since we overload update_mode based on queue_type
  7699.                 case when isnull(a.update_mode,0) = 4 then 2
  7700.                 when isnull(a.update_mode,0) = 5 then 3
  7701.                 else isnull(a.update_mode,0)
  7702.                 end,
  7703.                 a.last_sync_status,
  7704.                 a.last_sync_summary,
  7705.                 a.last_sync_time
  7706.                 from MSreplication_subscriptions s with (NOLOCK) 
  7707.                 left outer join MSsubscription_agents a with (NOLOCK) 
  7708.                     on (UPPER(s.publisher) = UPPER(a.publisher) and 
  7709.                         s.publisher_db = a.publisher_db and 
  7710.                         ((s.publication = a.publication and 
  7711.                         s.independent_agent = 1 and
  7712.                         a.publication <> N'ALL') or
  7713.                         (a.publication = N'ALL' and s.independent_agent = 0)) and
  7714.                         s.subscription_type = a.subscription_type)
  7715.                 where
  7716.                     ((@publisher = N'%') OR (UPPER(s.publisher) = UPPER(@publisher))) AND
  7717.                     ((@publisher_db = N'%') or ( s.publisher_db = @publisher_db)) and
  7718.                     ((s.subscription_type = 0 and @type_value = 0) or
  7719.                     -- For pull, return both pull and anonymous
  7720.                     (s.subscription_type <> 0 and @type_value = 1) or
  7721.                     @type_value = 2)             
  7722.         end
  7723.         -- Agents table does not exists.
  7724.         else if exists (select * from sysobjects where name='MSsubscription_properties ') 
  7725.         begin
  7726.             -- update_mode in MSreplication_subscriptions table is not reliable.
  7727.             insert into #MSenumpushsubscriptions select s.publisher, s.publisher_db, s.publication,
  7728.                 case isnull(p.publication_type,0) when 0 then 0 else 1 end,
  7729.                 s.subscription_type,
  7730.                 s.time, @cur_db, 
  7731.                 s.update_mode,
  7732.                 NULL, --a.last_sync_status,
  7733.                 NULL, --a.last_sync_summary,
  7734.                 NULL  --a.last_sync_time    
  7735.                 from MSreplication_subscriptions s with (NOLOCK) 
  7736.                 left outer join MSsubscription_properties p with (NOLOCK)
  7737.                     on (UPPER(s.publisher) = UPPER(p.publisher) and 
  7738.                         s.publisher_db = p.publisher_db and 
  7739.                         s.publication = p.publication and
  7740.                         -- don't use property table for push. 
  7741.                         s.subscription_type <> 0) 
  7742.                 where
  7743.                     ((@publisher = N'%') OR (UPPER(s.publisher) = UPPER(@publisher))) AND
  7744.                     ((@publisher_db = N'%') or ( s.publisher_db = @publisher_db)) and
  7745.                     ((s.subscription_type = 0 and @type_value = 0) or
  7746.                     -- For pull, return both pull and anonymous
  7747.                     (s.subscription_type <> 0 and @type_value = 1) or
  7748.                     @type_value = 2) 
  7749.         end
  7750.         -- Both table does not exists
  7751.         else
  7752.         begin
  7753.             -- update_mode in MSreplication_subscriptions table is not reliable.
  7754.             insert into #MSenumpushsubscriptions select s.publisher, s.publisher_db, s.publication,
  7755.                 0,
  7756.                 s.subscription_type,
  7757.                 s.time, @cur_db, 
  7758.                 s.update_mode,
  7759.                 NULL, -- a.last_sync_status,
  7760.                 NULL, -- a.last_sync_summary
  7761.                 NULL  -- a.last_sync_time
  7762.                 from MSreplication_subscriptions s with (NOLOCK)
  7763.                 where
  7764.                     ((@publisher = N'%') OR (UPPER(s.publisher) = UPPER(@publisher))) AND
  7765.                     ((@publisher_db = N'%') or ( s.publisher_db = @publisher_db)) and
  7766.                     ((s.subscription_type = 0 and @type_value = 0) or
  7767.                     -- For pull, return both pull and anonymous
  7768.                     (s.subscription_type <> 0 and @type_value = 1) or
  7769.                     @type_value = 2) 
  7770.         end
  7771.     
  7772.     end
  7773.     select * from #MSenumpushsubscriptions
  7774.     --drop table #MSenumpushsubscriptions
  7775.     return (0)
  7776. GO
  7777.  
  7778. grant execute on dbo.sp_MSenumsubscriptions to public
  7779. go 
  7780. exec dbo.sp_MS_marksystemobject sp_MSenumsubscriptions
  7781. GO
  7782.  
  7783. raiserror('Creating procedure sp_MSenumallpublications', 0,1)
  7784. go
  7785.  
  7786. CREATE PROCEDURE sp_MSenumallpublications(
  7787. @publisherdb sysname = '%', 
  7788. @replication_type tinyint = null, -- by default return all types of publication
  7789. @agent_login sysname = NULL,
  7790. @security_check bit = 1, -- Security check by default so that things depending on security 
  7791.                         -- filtering will not break immediately
  7792. @vendor_name sysname = NULL,    -- Use vender name to filter the result of third party publications.
  7793. @publication sysname = NULL
  7794. )
  7795. as
  7796. BEGIN
  7797.     set nocount on
  7798.     declare @dbname         sysname
  7799.     declare @trans             tinyint
  7800.     declare @merge             tinyint
  7801.     declare @3rdparty        tinyint
  7802.     declare @retcode        int
  7803.     DECLARE @dist_rpcname    sysname
  7804.     declare @distribdb        sysname
  7805.     declare @login            sysname
  7806.     declare @proc            nvarchar(255)
  7807.     declare @distbit        int
  7808.     declare @is_user_admin    bit
  7809.     declare @same_as_user    bit
  7810.  
  7811.     -- UI: If the distributor is not installed, return empty result
  7812.     if not exists (SELECT * FROM master.dbo.sysservers
  7813.               WHERE  srvstatus & 8 <> 0)
  7814.         return (0)
  7815.  
  7816.     -- UI: Win95 subscriber will send in null agent_login
  7817.     -- Assume the agent login to be the current login if it is NT login
  7818.     if @security_check = 1 and @agent_login is null
  7819.         and not exists (select * from master.dbo.syslogins where
  7820.             sid = suser_sid() and 
  7821.             isntname = 0)
  7822.         select @agent_login = suser_sname(suser_sid())
  7823.  
  7824.     /* Initializations */
  7825.     select @trans = 1 
  7826.     select @merge = 2
  7827.     select @3rdparty = 0
  7828.     select @login = suser_sname(suser_sid())
  7829.     SELECT @distbit = 16
  7830.     select @is_user_admin = 0
  7831.     select @same_as_user = 0
  7832.  
  7833.     -- Get publication list
  7834.     create table #pubdbs (publisher_db sysname collate database_default not null, replication_type int NOT NULL)
  7835.     create table #MSenumpublications 
  7836.             (publisher_db sysname collate database_default not null, publication sysname collate database_default not null, replication_type tinyint NOT NULL, 
  7837.             immediate_sync bit NOT NULL, allow_pull bit NOT NULL, allow_anonymous bit NOT NULL, 
  7838.             enabled_for_internet bit NOT NULL, repl_freq tinyint NOT NULL, immediate_sync_ready bit NOT NULL, 
  7839.             allow_sync_tran bit NOT NULL, independent_agent bit NOT NULL, is_db_owner int NOT NULL, 
  7840.             thirdparty_flag bit NOT NULL, vendor_name sysname collate database_default null, publisher sysname collate database_default null, 
  7841.             description nvarchar(255) collate database_default null, distribution_db sysname collate database_default null, 
  7842.             allow_queued_tran bit not null, allow_dts bit not null, thirdparty_options int null,
  7843.             queue_type int null, dynamic_filters bit not null default 0)
  7844.     create table #admin_publications (publisher_db sysname collate database_default not null, 
  7845.         publication sysname collate database_default not null)
  7846.     create table #agent_publications (publisher_db sysname collate database_default not null,
  7847.         publication sysname collate database_default not null)
  7848.  
  7849.     /* Return everything if @replication_type is not in (@3rdparty, @trans, @merge) */
  7850.     if not @replication_type in (@3rdparty, @trans, @merge)
  7851.         select @replication_type = null
  7852.  
  7853.     if @replication_type = @trans or @replication_type is null
  7854.         insert into #pubdbs select name, @trans from master.dbo.sysdatabases where 
  7855.             ((@publisherdb = N'%') or ( name = @publisherdb collate database_default)) and category & 1 <> 0 and 
  7856.             has_dbaccess(name) = 1
  7857.     if @replication_type = @merge or @replication_type is null
  7858.         insert into #pubdbs select name, @merge from master.dbo.sysdatabases where 
  7859.             ((@publisherdb = N'%') or ( name = @publisherdb collate database_default)) and category & 4 <> 0 and 
  7860.             has_dbaccess(name) = 1
  7861.     if @replication_type = @3rdparty
  7862.         insert into #pubdbs select name, @3rdparty from master.dbo.sysdatabases where 
  7863.             ((@publisherdb = N'%') or ( name = @publisherdb collate database_default)) and category & @distbit <> 0 and 
  7864.             has_dbaccess(name) = 1
  7865.  
  7866.     declare hCForEachDb CURSOR LOCAL FAST_FORWARD FOR select publisher_db, replication_type from  #pubdbs
  7867.     FOR READ ONLY
  7868.     open hCForEachDb
  7869.     fetch hCForEachDb into @dbname, @replication_type
  7870.     /* Loop for each database */
  7871.     while (@@fetch_status >= 0) 
  7872.     begin
  7873.         if (@replication_type) = @trans
  7874.             select @proc = quotename(@dbname) + '.dbo.sp_MSenumtranpublications'
  7875.         else if (@replication_type) = @merge
  7876.             select @proc = quotename(@dbname) + '.dbo.sp_MSenummergepublications'
  7877.         else if (@replication_type) = @3rdparty
  7878.             select @proc = quotename(@dbname) + '.dbo.sp_MSenum3rdpartypublications'
  7879.         if (@replication_type) = @3rdparty
  7880.             insert into #MSenumpublications exec @retcode = @proc @vendor_name, @publication
  7881.         else
  7882.             insert into #MSenumpublications exec @retcode = @proc @publication
  7883.  
  7884.         if @@ERROR <> 0 or @retcode <> 0
  7885.             return (1)
  7886.         fetch hCForEachDb into @dbname, @replication_type
  7887.     end /* while FETCH_SUCCESS */
  7888.  
  7889.     -- Prepare for filtering.
  7890.     IF EXISTS (SELECT * FROM msdb.dbo.sysobjects WHERE name = 'MSdistpublishers' and xtype = 'U') -- this is the distributor, check if publisher too
  7891.         if not exists (select * from msdb.dbo.MSdistpublishers where upper(name) = upper(@@SERVERNAME) collate database_default) -- not publisher
  7892.             select @security_check = 0     -- no need to go through security check for none-publisher 
  7893.                             -- since it won't have any publication other than third party ones.
  7894.                             
  7895.     IF (@security_check <> 0)
  7896.     BEGIN    
  7897.         EXEC @retcode = dbo.sp_helpdistributor     @rpcsrvname = @dist_rpcname OUTPUT,
  7898.                                                @distribdb   = @distribdb   OUTPUT
  7899.  
  7900.         IF @@error <> 0 OR @retcode <> 0
  7901.             RETURN (1)
  7902.  
  7903.         IF @distribdb is null
  7904.         BEGIN
  7905.             RAISERROR (14071, 16, -1)
  7906.             RETURN (1)
  7907.         END
  7908.  
  7909.         SELECT @proc = RTRIM(@dist_rpcname) + '.' + RTRIM(@distribdb) + '.dbo.sp_MSpublication_access'
  7910.  
  7911.         -- Optimization
  7912.         if is_srvrolemember('sysadmin') = 1
  7913.             select @is_user_admin = 1
  7914.         else
  7915.             insert into #admin_publications EXEC @retcode = @proc
  7916.                  @publisher = @@SERVERNAME,
  7917.                  @operation = 'get_publications',
  7918.                  @login = @login
  7919.  
  7920.         if suser_sid(@agent_login) = suser_sid()
  7921.             select @same_as_user = 1
  7922.         else
  7923.             insert into #agent_publications EXEC @retcode = @proc
  7924.                 @publisher = @@SERVERNAME,
  7925.                 @operation = 'get_publications',
  7926.                 @login = @agent_login
  7927.         
  7928.     END -- IF (@security_check <> 0) 
  7929.  
  7930.     -- commit open tran in case 
  7931.     -- insert into exec failed.
  7932.     while(@@trancount <> 0) commit tran
  7933.  
  7934.     select pub.publisher_db, pub.publication, pub.replication_type, 
  7935.             pub.immediate_sync, pub.allow_pull, pub.allow_anonymous, 
  7936.             pub.enabled_for_internet, pub.repl_freq, pub.immediate_sync_ready, 
  7937.             pub.allow_sync_tran, pub.independent_agent, N'agent_access' = case 
  7938.                 when 
  7939.                     (@same_as_user = 1 or
  7940.                     exists (select * from #agent_publications agent where
  7941.                     agent.publisher_db = pub.publisher_db and
  7942.                     agent.publication = pub.publication))
  7943.                     then convert(bit,1)
  7944.                 else convert(bit,0)
  7945.                 end,
  7946.             pub.thirdparty_flag,
  7947.             pub.vendor_name, pub.publisher, pub.description, pub.distribution_db, 
  7948.             allow_queued_tran, allow_dts, pub.thirdparty_options, pub.queue_type, pub.dynamic_filters
  7949.      from #MSenumpublications pub where exists (select * from #admin_publications admin where
  7950.         pub.publisher_db = admin.publisher_db and
  7951.         pub.publication = admin.publication) or
  7952.         @security_check = 0 or
  7953.         pub.is_db_owner = 1 or
  7954.         @is_user_admin = 1
  7955.      order by pub.publication, pub.publisher_db
  7956.  
  7957.     return (0)
  7958. END
  7959. go
  7960.  
  7961. grant execute on dbo.sp_MSenumallpublications to public
  7962. go 
  7963.  
  7964. raiserror('Creating procedure sp_MSenumtranpublications', 0,1)
  7965. go
  7966.  
  7967. CREATE PROCEDURE sp_MSenumtranpublications (
  7968. @publication sysname
  7969. )
  7970. as
  7971. BEGIN
  7972.     set nocount on
  7973.     select db_name(), name, 1, immediate_sync, allow_pull, allow_anonymous, 
  7974.         enabled_for_internet, repl_freq, immediate_sync_ready, 
  7975.         allow_sync_tran, independent_agent, is_member('db_owner'),
  7976.         0, -- thirdparty
  7977.         'Microsoft SQL Server', @@servername, description,
  7978.         convert(sysname, null),
  7979.         allow_queued_tran,
  7980.         allow_dts
  7981.         ,convert(int,null) -- thirdparty_options
  7982.         ,queue_type
  7983.         ,0 -- dynamic_filters
  7984.         from syspublications pubs
  7985.         where exists (select * from sysextendedarticlesview art where pubs.pubid = art.pubid) 
  7986.             and status <> 0
  7987.             and (pubs.name = @publication or @publication is null)
  7988. END
  7989. go
  7990.  
  7991. raiserror('Creating procedure sp_MSenummergepublications', 0,1)
  7992. go
  7993.  
  7994. CREATE PROCEDURE sp_MSenummergepublications (
  7995. @publication sysname
  7996. )
  7997. as
  7998. BEGIN
  7999.     declare @publisher            sysname
  8000.     declare @publisher_db        sysname
  8001.  
  8002.     select @publisher=@@SERVERNAME
  8003.     select @publisher_db=db_name()
  8004.     
  8005.     set nocount on
  8006.     select db_name(), name, 2, 1, allow_pull, allow_anonymous, enabled_for_internet, 0, snapshot_ready, 0, 1, is_member('db_owner'),
  8007.         0, --thirdparty
  8008.         'Microsoft SQL Server', publisher, description,
  8009.         convert(sysname, null),
  8010.         convert(bit,0), --allow_queued_tran
  8011.         convert(bit,0) --allow_dts
  8012.         ,convert(int, null) -- thirdparty_options
  8013.         ,convert(int, null) -- queue_type
  8014.         ,dynamic_filters 
  8015.         from 
  8016.         sysmergepublications p where status <> 0 
  8017.         and LOWER(publisher)=LOWER(@publisher) 
  8018.         and publisher_db=@publisher_db
  8019.         and (p.name = @publication or @publication is null)
  8020.  
  8021. END
  8022. go
  8023.  
  8024. raiserror('Creating procedure sp_MSenum3rdpartypublications', 0,1)
  8025. go
  8026.  
  8027. CREATE PROCEDURE sp_MSenum3rdpartypublications (
  8028.     @vendor_name sysname,
  8029.     @publication sysname
  8030. )
  8031. as
  8032. BEGIN
  8033.     set nocount on
  8034.     select pubs.publisher_db, publication, 
  8035.         case when publication_type <> 2 then 1
  8036.         else 2
  8037.         end,  --replication_type, 1 tran, 2 merge ; pub type 0 tran 1 snapshot, 2 merge
  8038.         immediate_sync, allow_pull, allow_anonymous, 
  8039.         0,    --enabled_for_internet,
  8040.         case when publication_type = 0 then 0
  8041.         else 1
  8042.         end,  --repl_freq, 
  8043.         1,    --immediate_sync_ready, always return 1 so that UI will not warn
  8044.         0,    -- allow_sync_tran, 
  8045.         independent_agent, 
  8046.         is_member('db_owner'),
  8047.         1, --thirdparty
  8048.         pubs.vendor_name,
  8049.         srv.srvname,
  8050.         pubs.description,
  8051.         db_name(),
  8052.         convert(bit,0), --allow_queued_tran
  8053.         convert(bit,0) --allow_dts
  8054.         ,thirdparty_options
  8055.         ,convert(int, null) -- queue_type
  8056.         ,0 -- dynamic_filters
  8057.         from MSpublications pubs, master..sysservers srv
  8058.         where exists (select * from MSarticles art where 
  8059.                 pubs.publication_id = art.publication_id)  and
  8060.             thirdparty_flag <> 0 and
  8061.             publisher_id = srvid and
  8062.             (@vendor_name <> 'others' and vendor_name = @vendor_name or 
  8063.              @vendor_name  = 'others' and (vendor_name is null or vendor_name = '') or
  8064.              @vendor_name is null ) and
  8065.              (pubs.publication = @publication or @publication is null)
  8066. END
  8067. go
  8068.  
  8069.  
  8070. raiserror('Creating procedure sp_MSenumthirdpartypublicationvendornames', 0,1)
  8071. go
  8072.  
  8073. CREATE PROCEDURE sp_MSenumthirdpartypublicationvendornames(
  8074. @within_db bit = 0
  8075. )
  8076.  
  8077. as
  8078.     set nocount on
  8079.     if @within_db = 0
  8080.     begin
  8081.         declare @dbname         sysname
  8082.         declare @retcode        int
  8083.         declare @distbit        int
  8084.         declare @proc            nvarchar(300)
  8085.  
  8086.         --init
  8087.         SELECT @distbit = 16
  8088.  
  8089.         -- Get publication list
  8090.         create table #pubdbs (publisher_db sysname collate database_default not null)
  8091.  
  8092.         insert into #pubdbs select name from master..sysdatabases where 
  8093.             category & @distbit <> 0 and 
  8094.             has_dbaccess(name) = 1
  8095.  
  8096.         create table #MSenumpublications 
  8097.                 (vendor_name sysname collate database_default not null)
  8098.  
  8099.         declare hCForEachDb CURSOR LOCAL FAST_FORWARD FOR select publisher_db from  #pubdbs
  8100.         FOR READ ONLY
  8101.         open hCForEachDb
  8102.         fetch hCForEachDb into @dbname
  8103.         /* Loop for each database */
  8104.         while (@@fetch_status >= 0) 
  8105.         begin
  8106.             select @proc = quotename(@dbname) + 
  8107.                 '.dbo.sp_MSenumthirdpartypublicationvendornames'
  8108.             insert into #MSenumpublications exec @retcode = @proc 1
  8109.             if @@ERROR <> 0 or @retcode <> 0
  8110.                 return (1)
  8111.             fetch hCForEachDb into @dbname
  8112.         end /* while FETCH_SUCCESS */
  8113.     end
  8114.     else
  8115.     begin
  8116.         select distinct vendor_name from MSpublications where thirdparty_flag = 1 and
  8117.             vendor_name is not null and vendor_name <> ''
  8118.     end
  8119.  
  8120.     select distinct vendor_name from #MSenumpublications  order by vendor_name
  8121.  
  8122.     return (0)
  8123. go
  8124.  
  8125. grant execute on dbo.sp_MSenumthirdpartypublicationvendornames to public
  8126. go 
  8127.  
  8128. dump tran master with no_log
  8129. GO
  8130.  
  8131. raiserror('Creating procedure sp_reinitpullsubscription', 0,1)
  8132. go
  8133.  
  8134. CREATE PROCEDURE sp_reinitpullsubscription (
  8135.     @publisher sysname,
  8136.     @publisher_db sysname,
  8137.     @publication sysname = 'all'                       /* publication name */
  8138.     )AS
  8139.  
  8140.     SET NOCOUNT ON
  8141.     
  8142.     declare @subscription_type int    
  8143.     declare @sync_type tinyint
  8144.     /*
  8145.     ** Security Check
  8146.     */
  8147.     
  8148.       declare @retcode     int  
  8149.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  8150.     IF @@ERROR <> 0 or @retcode <> 0
  8151.         RETURN(1)
  8152.  
  8153.     /*
  8154.     ** Initializations.
  8155.     */
  8156.    
  8157.     /*
  8158.     ** Parameter Check: @publisher
  8159.     ** Check to make sure that the publisher is define
  8160.     */
  8161.     IF @publisher IS NULL
  8162.     BEGIN
  8163.         RAISERROR (14043, 16, -1, '@publisher')
  8164.         RETURN (1)
  8165.     END
  8166.  
  8167.     IF @publisher = 'all'
  8168.     BEGIN
  8169.         RAISERROR (14136, 16, -1)
  8170.         RETURN (1)
  8171.     END
  8172.  
  8173.     EXECUTE @retcode = dbo.sp_validname @publisher
  8174.  
  8175.     IF @@ERROR <> 0 OR @retcode <> 0
  8176.        RETURN (1)
  8177.     
  8178.  
  8179.     /*
  8180.     ** Parameter Check: @publisher_db
  8181.     */
  8182.  
  8183.     IF @publisher_db IS NULL
  8184.     BEGIN
  8185.         RAISERROR (14043, 16, -1, '@publisher_db')
  8186.         RETURN (1)
  8187.     END
  8188.  
  8189.     IF @publisher_db = 'all'
  8190.     BEGIN
  8191.         RAISERROR (14136, 16, -1)
  8192.         RETURN (1)
  8193.     END
  8194.  
  8195.     EXECUTE @retcode = dbo.sp_validname @publisher_db
  8196.  
  8197.     IF @@ERROR <> 0 OR @retcode <> 0
  8198.        RETURN (1)
  8199.  
  8200.     /*
  8201.     ** Parameter Check: @publication
  8202.     ** 
  8203.     */
  8204.     IF @publication IS NULL
  8205.     BEGIN
  8206.         RAISERROR (14043, 16, -1, '@publication')
  8207.         RETURN (1)
  8208.     END
  8209.  
  8210.     IF LOWER(@publication) = 'all'
  8211.         select @publication = '%'
  8212.     ELSE
  8213.     BEGIN
  8214.         EXECUTE @retcode = dbo.sp_validname @publication
  8215.  
  8216.         IF @@ERROR <> 0 OR @retcode <> 0
  8217.         RETURN (1)
  8218.     END
  8219.         
  8220.     IF NOT EXISTS (SELECT * FROM  MSreplication_subscriptions 
  8221.                 WHERE UPPER(publisher) = UPPER(@publisher) AND
  8222.                       publisher_db  = @publisher_db AND
  8223.                       publication like @publication )
  8224.     BEGIN
  8225.             RAISERROR(14135, 11, -1,  @publisher, @publisher_db, @publication)
  8226.             RETURN(1)
  8227.     END
  8228.         
  8229.     select @sync_type = immediate_sync 
  8230.         from MSreplication_subscriptions
  8231.         WHERE UPPER(publisher) = UPPER(@publisher) AND publisher_db  = @publisher_db AND publication like @publication 
  8232.  
  8233.     IF @sync_type = 0
  8234.     BEGIN
  8235.         raiserror(21059, 16, -1)
  8236.         return (1)
  8237.     END
  8238.         
  8239.     UPDATE MSreplication_subscriptions set 
  8240.         transaction_timestamp = 0x00
  8241.         WHERE UPPER(publisher) = UPPER(@publisher) AND
  8242.                       publisher_db  = @publisher_db AND
  8243.                       publication like @publication 
  8244.     if @@ERROR<>0 
  8245.         RETURN (1)
  8246.  
  8247.     -- Reset the attach state so that the distribution agent will not adjust attach state.
  8248.     if @publication <> '%'
  8249.     begin
  8250.         select @subscription_type = subscription_type from MSreplication_subscriptions
  8251.             WHERE UPPER(publisher) = UPPER(@publisher) AND
  8252.                           publisher_db  = @publisher_db AND
  8253.                           publication = @publication and
  8254.                           -- Don't do this for push
  8255.                           subscription_type <> 0
  8256.         if @subscription_type is not null
  8257.         begin
  8258.             exec @retcode = dbo.sp_MSreset_attach_state 
  8259.                 @publisher = @publisher,
  8260.                 @publisher_db = @publisher_db,
  8261.                 @publication = @publication,
  8262.                 @subscription_type = @subscription_type
  8263.             if @retcode <> 0 or @@error <> 0
  8264.                 return (1)
  8265.         end
  8266.     end
  8267. GO
  8268.  
  8269. grant execute on dbo.sp_reinitpullsubscription to public
  8270. go
  8271.     
  8272. raiserror('Creating procedure sp_addpullsubscription', 0,1)
  8273. go
  8274.  
  8275. CREATE PROCEDURE sp_addpullsubscription (
  8276.     @publisher sysname,
  8277.     @publisher_db sysname,
  8278.     @publication sysname,    /* publication name */
  8279.     @independent_agent nvarchar(5) = 'true',  /* true or false */
  8280.     @subscription_type nvarchar(9) = 'anonymous',     /* subscription_type, pull or anonymous */
  8281.     @description nvarchar(100) = NULL,
  8282.     -- SyncTran
  8283.     @update_mode          nvarchar(15) = 'read only', -- 'sync tran', 'queued tran', 'failover'
  8284.     @immediate_sync        bit = 1
  8285. ) AS
  8286. BEGIN
  8287.  
  8288.     SET NOCOUNT ON
  8289.  
  8290.     /*
  8291.     ** Declarations.
  8292.     */
  8293.  
  8294.     DECLARE @retcode int
  8295.     DECLARE @subscription_type_id int   /* 1 = pull, 2 = anonymous */
  8296.     DECLARE @independent_agent_id bit
  8297.     -- SyncTran
  8298.     DECLARE @update_mode_id     tinyint 
  8299.  
  8300.     -- For attach
  8301.     if exists (select * from sysobjects where name = 'MSrepl_restore_stage')
  8302.     begin
  8303.         raiserror(21211, 16, -1)
  8304.         return 1
  8305.     end
  8306.  
  8307.     /* 
  8308.     ** Check if replication components are installed on this server
  8309.     */
  8310.     exec @retcode = dbo.sp_MS_replication_installed
  8311.     if (@retcode <> 1)
  8312.     begin
  8313.         return (1)
  8314.     end
  8315.     
  8316.     /*
  8317.     ** Security Check
  8318.     */
  8319.  
  8320.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  8321.     IF @@ERROR <> 0 or @retcode <> 0
  8322.         RETURN(1)
  8323.  
  8324.     /*
  8325.     ** Initializations.
  8326.     */
  8327.  
  8328.     /*
  8329.     ** Parameter Check: @publisher
  8330.     ** Check to make sure that the publisher is define
  8331.     */
  8332.     IF @publisher IS NULL
  8333.     BEGIN
  8334.         RAISERROR (14043, 16, -1, '@publisher')
  8335.         RETURN (1)
  8336.     END
  8337.  
  8338.     IF @publisher = 'all'
  8339.     BEGIN
  8340.         RAISERROR (14136, 16, -1)
  8341.         RETURN (1)
  8342.     END
  8343.  
  8344.     EXECUTE @retcode = dbo.sp_validname @publisher
  8345.  
  8346.     IF @@ERROR <> 0 OR @retcode <> 0
  8347.        RETURN (1)
  8348.     
  8349.  
  8350.     /*
  8351.     ** Parameter Check: @publisher_db
  8352.     */
  8353.  
  8354.     IF @publisher_db IS NULL
  8355.     BEGIN
  8356.         RAISERROR (14043, 16, -1, '@publisher_db')
  8357.         RETURN (1)
  8358.     END
  8359.  
  8360.     IF @publisher_db = 'all'
  8361.     BEGIN
  8362.         RAISERROR (14136, 16, -1)
  8363.         RETURN (1)
  8364.     END
  8365.  
  8366.     EXECUTE @retcode = dbo.sp_validname @publisher_db
  8367.  
  8368.     IF @@ERROR <> 0 OR @retcode <> 0
  8369.        RETURN (1)
  8370.  
  8371.     /*
  8372.     ** Parameter Check: @publication
  8373.     ** 
  8374.     */
  8375.     IF @publication IS NULL
  8376.     BEGIN
  8377.         RAISERROR (14043, 16, -1, '@publication')
  8378.         RETURN (1)
  8379.     END
  8380.  
  8381.     IF @publication = 'all'
  8382.     BEGIN
  8383.         RAISERROR (14136, 16, -1)
  8384.         RETURN (1)
  8385.     END
  8386.  
  8387.     EXECUTE @retcode = dbo.sp_validname @publication
  8388.  
  8389.     IF @@ERROR <> 0 OR @retcode <> 0
  8390.        RETURN (1)
  8391.  
  8392.     IF @independent_agent IS NULL OR LOWER(@independent_agent collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('true', 'false')
  8393.         BEGIN
  8394.             RAISERROR (14148, 16, -1, '@independent_agent')
  8395.             RETURN (1)
  8396.         END
  8397.  
  8398.     IF LOWER(@independent_agent collate SQL_Latin1_General_CP1_CS_AS) = 'true' SELECT @independent_agent_id = 1
  8399.     ELSE SELECT @independent_agent_id = 0
  8400.     /*
  8401.     ** Parameter Check:  @subscription_type
  8402.     ** The @status value can be:
  8403.     **
  8404.     **      type_id            type
  8405.     **      ======            ========
  8406.     **             0              push
  8407.     **           1            pull
  8408.     **           2            anonymous
  8409.     **
  8410.     **    Note: @subscription_type = push is only used by distribution agents
  8411.     */
  8412.     
  8413.     IF @subscription_type IS NULL OR LOWER(@subscription_type collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('push', 'pull','anonymous')
  8414.     BEGIN
  8415.         RAISERROR (20016, 16, -1)
  8416.         RETURN (1)
  8417.     END
  8418.  
  8419.  
  8420.     IF LOWER(@subscription_type collate SQL_Latin1_General_CP1_CS_AS) = 'pull'    
  8421.         SELECT @subscription_type_id = 1
  8422.     ELSE IF LOWER(@subscription_type collate SQL_Latin1_General_CP1_CS_AS) = 'anonymous'  
  8423.         SELECT @subscription_type_id = 2
  8424.     ELSE
  8425.         SELECT @subscription_type_id = 0
  8426.  
  8427.     IF @independent_agent_id = 0 AND @subscription_type_id = 2
  8428.     BEGIN
  8429.         RAISERROR (21026, 16, -1)
  8430.         RETURN (1)
  8431.     END
  8432.  
  8433.     -- SyncTran
  8434.     /*
  8435.     **  Parameter check: @update_mode
  8436.     */
  8437.     /*
  8438.     ** Parameter check: @update_mode
  8439.     */
  8440.     IF (@update_mode IS NULL OR LOWER(@update_mode collate SQL_Latin1_General_CP1_CS_AS) NOT IN 
  8441.         ('read only', 'sync tran', 'queued tran', 'failover'))
  8442.     BEGIN
  8443.         RAISERROR (20502, 16, -1, '@update_mode')
  8444.         RETURN (1)
  8445.     END
  8446.  
  8447.     -- Anonymous subscriptions should not be allowed to 
  8448.     -- subscribe with 'synctran option'    
  8449.     IF LOWER(@update_mode collate SQL_Latin1_General_CP1_CS_AS) in ('sync tran', 'queued tran', 'failover') and
  8450.         @subscription_type_id = 2 
  8451.     begin                      
  8452.            RAISERROR (21057, 16, -1)
  8453.         RETURN (1)
  8454.     end
  8455.  
  8456.     select @update_mode_id = 
  8457.     case
  8458.         when LOWER(@update_mode collate SQL_Latin1_General_CP1_CS_AS) = 'sync tran' then 1
  8459.         when LOWER(@update_mode collate SQL_Latin1_General_CP1_CS_AS) = 'queued tran' then 4
  8460.         when LOWER(@update_mode collate SQL_Latin1_General_CP1_CS_AS) = 'failover' then 5
  8461.         else 0
  8462.     end
  8463.  
  8464.  
  8465.     begin tran
  8466.     save TRAN addpullsubscription
  8467.     
  8468.     /* 
  8469.     ** Check to see if MSreplication_subscriptions and MSsubscription_properties 
  8470.     ** tables exists.
  8471.     ** If not, create it.
  8472.     */
  8473.  
  8474.     exec @retcode = dbo.sp_MScreate_sub_tables
  8475.         @tran_sub_table = 1,
  8476.         @property_table = 1
  8477.     IF @@ERROR <> 0 or @retcode <> 0
  8478.         goto UNDO
  8479.     
  8480.     /*
  8481.     ** Check to make sure that the subscription does not already exist
  8482.     */
  8483.     declare @sub_type int
  8484.     select @sub_type = subscription_type from MSreplication_subscriptions 
  8485.                 WHERE UPPER(publisher) = UPPER(@publisher) AND
  8486.                       publisher_db  = @publisher_db AND
  8487.                       publication = @publication
  8488.  
  8489.     -- It is not allowed to subscribe to the same publication twice even with
  8490.     -- differnet subscription type. 
  8491.     -- Raise special error for push
  8492.     if @sub_type is not null
  8493.         if @sub_type = 0
  8494.         begin
  8495.             raiserror (20594, 16, -1)
  8496.             GOTO UNDO            
  8497.         end
  8498.         else
  8499.         begin
  8500.             RAISERROR (14058, 16, -1)
  8501.             GOTO UNDO
  8502.         end
  8503.   
  8504.     /*
  8505.     ** Add the subscription
  8506.     */
  8507.  
  8508.     INSERT MSreplication_subscriptions  (publisher,
  8509.                                     publisher_db,
  8510.                                     publication,
  8511.                                     independent_agent,
  8512.                                     subscription_type,
  8513.                                     distribution_agent,
  8514.                                     description,
  8515.                                     time,
  8516.                                     transaction_timestamp,
  8517.                                     -- SyncTran
  8518.                                     update_mode,
  8519.                                     immediate_sync)
  8520.        VALUES (@publisher,
  8521.                    @publisher_db,
  8522.                    @publication,
  8523.                    @independent_agent_id,    
  8524.                    @subscription_type_id,
  8525.                    NULL,
  8526.                    @description,
  8527.                    getdate(),
  8528.                    0,
  8529.                    -- SyncTran
  8530.                    @update_mode_id,
  8531.                    @immediate_sync
  8532.                    )
  8533.     IF @@ERROR <> 0
  8534.     BEGIN
  8535.        RAISERROR (14057, 16, -1)
  8536.        GOTO UNDO
  8537.     END
  8538.  
  8539.     COMMIT TRAN
  8540.  
  8541.     RETURN (0)
  8542.  
  8543. UNDO:
  8544.     IF @@TRANCOUNT > 0
  8545.     begin
  8546.         ROLLBACK TRAN addpullsubscription
  8547.         COMMIT TRAN   
  8548.     end
  8549.     return 1
  8550. END
  8551. go
  8552.  
  8553. raiserror('Creating procedure sp_MSupdatesharedagentproperties', 0,1)
  8554. go
  8555.  
  8556. CREATE PROCEDURE sp_MSupdatesharedagentproperties (
  8557.     @publisher sysname,
  8558.     @publisher_db sysname,
  8559.     @publication sysname,
  8560.     @property    sysname,
  8561.     @strvalue    nvarchar(256) = NULL,
  8562.     @intvalue    int = NULL,
  8563.     @subscription_type int     
  8564.     )
  8565. AS
  8566.  
  8567.  
  8568.     -- Note publisher/publisher_db/publication uniquely identifies 
  8569.     -- a subscription in MSreplication_subscriptions 
  8570.     CREATE TABLE #subscriptions
  8571.     (
  8572.         publication sysname collate database_default
  8573.     )
  8574.  
  8575.     -- Compute the list of affected subscriptions
  8576.     INSERT INTO #subscriptions SELECT publication FROM
  8577.     MSreplication_subscriptions WHERE UPPER(publisher) = UPPER(@publisher)
  8578.     AND publisher_db = @publisher_db AND publication <> @publication
  8579.     AND independent_agent = 0 AND subscription_type = @subscription_type
  8580.  
  8581.     IF (SELECT COUNT(*) FROM #subscriptions) > 0
  8582.     BEGIN 
  8583.  
  8584.         IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'distributor'
  8585.         BEGIN
  8586.             UPDATE MSsubscription_properties SET distributor = @strvalue 
  8587.              WHERE UPPER(publisher) = UPPER(@publisher)  
  8588.                AND publisher_db = @publisher_db
  8589.                AND publication in (SELECT publication FROM #subscriptions)   
  8590.         END
  8591.         ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'distributor_security_mode'
  8592.         BEGIN
  8593.             UPDATE MSsubscription_properties SET distributor_security_mode = @intvalue 
  8594.              WHERE UPPER(publisher) = UPPER(@publisher)  
  8595.                AND publisher_db = @publisher_db
  8596.                AND publication in (SELECT publication FROM #subscriptions)   
  8597.         END
  8598.         ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'distributor_login'
  8599.         BEGIN
  8600.             UPDATE MSsubscription_properties SET distributor_login = @strvalue 
  8601.              WHERE UPPER(publisher) = UPPER(@publisher)  
  8602.                AND publisher_db = @publisher_db
  8603.                AND publication in (SELECT publication FROM #subscriptions)   
  8604.         END
  8605.         ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'distributor_password'
  8606.         BEGIN
  8607.             UPDATE MSsubscription_properties SET distributor_password = @strvalue 
  8608.              WHERE UPPER(publisher) = UPPER(@publisher)  
  8609.                AND publisher_db = @publisher_db
  8610.                AND publication in (SELECT publication FROM #subscriptions)   
  8611.         END
  8612.         ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'distributor_password'
  8613.         BEGIN
  8614.             UPDATE MSsubscription_properties SET distributor_password = @strvalue 
  8615.              WHERE UPPER(publisher) = UPPER(@publisher)  
  8616.                AND publisher_db = @publisher_db
  8617.                AND publication in (SELECT publication FROM #subscriptions)   
  8618.         END
  8619.         ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'ftp_address'
  8620.         BEGIN
  8621.             UPDATE MSsubscription_properties SET ftp_address = @strvalue 
  8622.              WHERE UPPER(publisher) = UPPER(@publisher)  
  8623.                AND publisher_db = @publisher_db
  8624.                AND publication in (SELECT publication FROM #subscriptions)   
  8625.         END
  8626.         ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'ftp_port'
  8627.         BEGIN
  8628.             UPDATE MSsubscription_properties SET ftp_port = @intvalue 
  8629.              WHERE UPPER(publisher) = UPPER(@publisher)  
  8630.                AND publisher_db = @publisher_db
  8631.                AND publication in (SELECT publication FROM #subscriptions)   
  8632.         END
  8633.         ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'ftp_login'
  8634.         BEGIN
  8635.             UPDATE MSsubscription_properties SET ftp_login = @strvalue 
  8636.              WHERE UPPER(publisher) = UPPER(@publisher)  
  8637.                AND publisher_db = @publisher_db
  8638.                AND publication in (SELECT publication FROM #subscriptions)   
  8639.         END
  8640.         ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'ftp_password'
  8641.         BEGIN
  8642.             UPDATE MSsubscription_properties SET ftp_password = @strvalue 
  8643.              WHERE UPPER(publisher) = UPPER(@publisher)  
  8644.                AND publisher_db = @publisher_db
  8645.                AND publication in (SELECT publication FROM #subscriptions)   
  8646.         END
  8647.         ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'alt_snapshot_folder'
  8648.         BEGIN
  8649.             UPDATE MSsubscription_properties SET alt_snapshot_folder = @strvalue 
  8650.              WHERE UPPER(publisher) = UPPER(@publisher)  
  8651.                AND publisher_db = @publisher_db
  8652.                AND publication in (SELECT publication FROM #subscriptions)   
  8653.         END
  8654.         ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'working_directory'
  8655.         BEGIN
  8656.             UPDATE MSsubscription_properties SET working_directory = @strvalue 
  8657.              WHERE UPPER(publisher) = UPPER(@publisher)  
  8658.                AND publisher_db = @publisher_db
  8659.                AND publication in (SELECT publication FROM #subscriptions)   
  8660.         END
  8661.         ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'use_ftp'
  8662.         BEGIN
  8663.             UPDATE MSsubscription_properties SET use_ftp = @intvalue 
  8664.              WHERE UPPER(publisher) = UPPER(@publisher)  
  8665.                AND publisher_db = @publisher_db
  8666.                AND publication in (SELECT publication FROM #subscriptions)   
  8667.         END
  8668.         ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'offload_agent'
  8669.         BEGIN
  8670.             UPDATE MSsubscription_properties SET offload_agent = @intvalue
  8671.              WHERE UPPER(publisher) = UPPER(@publisher)
  8672.                AND publisher_db = @publisher_db
  8673.                AND publication in (SELECT publication FROM #subscriptions)
  8674.         END
  8675.         ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'offload_server'
  8676.         BEGIN
  8677.             UPDATE MSsubscription_properties SET offload_server = @strvalue
  8678.              WHERE UPPER(publisher) = UPPER(@publisher)
  8679.                AND publisher_db = @publisher_db
  8680.                AND publication in (SELECT publication FROM #subscriptions)
  8681.         END
  8682.     END
  8683.  
  8684.     DROP TABLE #subscriptions
  8685.  
  8686.     IF @@ERROR <> 0
  8687.         RETURN 1
  8688.     ELSE
  8689.         RETURN 0
  8690. GO 
  8691.  
  8692. /* Create  sp_replicationdboption */
  8693. raiserror('Creating procedure sp_replicationdboption', 0,1)
  8694. GO
  8695.  
  8696. CREATE PROCEDURE sp_replicationdboption (
  8697.       @dbname    sysname,
  8698.       @optname   sysname,
  8699.       @value     sysname,
  8700.       @ignore_distributor bit = 0,
  8701.       @from_scripting bit = 0
  8702.     ) AS
  8703.  
  8704.     SET NOCOUNT ON
  8705.  
  8706.     /*
  8707.     ** Declarations.
  8708.     */
  8709.     
  8710.     declare @alert_name     sysname
  8711.     declare @alert_id       int
  8712.     declare @command        nvarchar(255)
  8713.     declare @description    nvarchar(500)
  8714.     declare @category_name  sysname
  8715.     declare @agentname      sysname
  8716.     DECLARE @retcode        int
  8717.     DECLARE @optbit         int
  8718.     DECLARE @optbit_value   int /* Desired value with the optbit mask */
  8719.     DECLARE @proc           nvarchar(255)
  8720.         , @category int
  8721.  
  8722.     /*
  8723.     ** Initialization
  8724.     */
  8725.  
  8726.     /*
  8727.     ** Parameter check
  8728.     ** @dbname
  8729.     */
  8730.     SELECT @category = category FROM master.dbo.sysdatabases WHERE
  8731.         name = @dbname collate database_default
  8732.     if @category is null
  8733.     BEGIN
  8734.         RAISERROR(15010, 16, -1, @dbname)
  8735.         RETURN(1)
  8736.     END
  8737.  
  8738.     /*
  8739.     ** Parameter check
  8740.     ** @type
  8741.     */
  8742.     IF @optname is null or LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('publish',
  8743.         'merge publish',
  8744.         'subscribe', -- Used by sp_dboption for backward compatibility only.
  8745.         'sync with backup',
  8746.         'max cmds in tran'
  8747.         )
  8748.     BEGIN
  8749.         RAISERROR(14138,16,-1,@optname)
  8750.         RETURN(1)
  8751.     END
  8752.  
  8753.     /*
  8754.     ** Parameter check
  8755.     ** @value
  8756.     */
  8757.     IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('true','false')
  8758.     BEGIN
  8759.       RAISERROR(14137,16,-1)
  8760.       RETURN(1)
  8761.     END
  8762.  
  8763.     /*
  8764.     ** Security Check
  8765.     */
  8766.     -- This proc is not granted to public. Only other system proc or sysadmin can use this
  8767.     -- sp_dboption will call this and it has its own security check,
  8768.  
  8769.     /*
  8770.     **  If we're in a transaction, disallow this since it might make recovery
  8771.     **  impossible.
  8772.     **
  8773.     */
  8774.     IF @@trancount > 0 
  8775.     BEGIN
  8776.         RAISERROR(15002,16,-1,'sp_replicationdboption')
  8777.         RETURN(1)
  8778.     END
  8779.     
  8780.     IF LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) = 'publish'
  8781.         BEGIN
  8782.             SELECT @optbit = 1
  8783.             SELECT @proc = QUOTENAME(@dbname) + '.dbo.sp_MSpublishdb'
  8784.         END
  8785.     ELSE IF LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) = 'merge publish'
  8786.         BEGIN
  8787.             SELECT @optbit = 4
  8788.             SELECT @proc = QUOTENAME(@dbname) + '.dbo.sp_MSmergepublishdb'
  8789.         END
  8790.     ELSE IF LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) = 'subscribe'
  8791.         BEGIN
  8792.             SELECT @optbit = 2
  8793.         END
  8794.     ELSE IF LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) = 'sync with backup'
  8795.         BEGIN
  8796.             SELECT @optbit = 32
  8797.         END
  8798.     ELSE IF LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) = 'max cmds in tran'
  8799.         BEGIN
  8800.             SELECT @optbit = 64
  8801.         END
  8802.  
  8803.     IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) = 'true'
  8804.         SELECT @optbit_value = @optbit
  8805.     ELSE
  8806.         SELECT @optbit_value = 0
  8807.  
  8808.           
  8809.     /*
  8810.     ** Check if the option is set as required already
  8811.     */
  8812.     if (@category & @optbit) = @optbit_value 
  8813.     BEGIN
  8814.         if @optbit_value = 64 -- setting 'max cmds in tran' to the same, do nothing
  8815.             RETURN (0)
  8816.         if LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) = 'true'
  8817.             RAISERROR (14035, 10, -1, @optname, @dbname)        
  8818.         else
  8819.             RAISERROR (14037, 10, -1, @optname, @dbname)
  8820.         RETURN (1)
  8821.     END
  8822.  
  8823.     -- If turning on 'sync with backup', make sure 'publish' or 'dist' is turned on already.
  8824.     if  @optbit_value = 32 and (@category & 1 = 0 and @category & 16 = 0)
  8825.     begin
  8826.         raiserror(20019, 16, -1, 'sync with backup')
  8827.         return (1)
  8828.     end
  8829.     if  @optbit_value = 64 and (@category & 16 = 0)
  8830.     begin
  8831.         raiserror(20019, 16, -1, 'max cmds in tran')
  8832.         return (1)
  8833.     end
  8834.  
  8835.     -- We do not allow turning on sync with backup mode at publishing db if the db is
  8836.     -- in simple recovery mode
  8837.     if  @optbit_value = 32 and @category & 1 <> 0 and 
  8838.         databasepropertyex(@dbname, 'recovery') = 'SIMPLE'
  8839.     begin
  8840.         raiserror(20622, 16, -1, 'sync with backup')
  8841.         return (1)
  8842.     end
  8843.     
  8844.     -- If turning off 'publish', turn off 'sync with backup' as well if the database
  8845.     -- is not a distribution database.
  8846.     if @optbit = 1 and @optbit_value = 0 and @category & 32 <> 0 and @category & 16 = 0
  8847.     begin
  8848.         EXEC @retcode =  dbo.sp_replicationdboption   
  8849.             @dbname = @dbname,
  8850.             @optname = 'sync with backup',
  8851.             @value = 'false',
  8852.             @ignore_distributor = @ignore_distributor,
  8853.             @from_scripting = @from_scripting
  8854.         IF @@ERROR <> 0 or @retcode <> 0
  8855.         BEGIN
  8856.             GOTO UNDO
  8857.         END
  8858.     end
  8859.  
  8860.     -- if turning on 'sync with backup' a distribution database, initialize the backup lsns 
  8861.     -- to nulls, this should be done before the category bit is set.
  8862.     declare @backup_proc nvarchar(1000)
  8863.     if @optbit_value = 32 and @category & 16 <> 0
  8864.     begin
  8865.         SELECT @backup_proc = QUOTENAME(@dbname) + 
  8866.             '.dbo.sp_MSrepl_init_backup_lsns'
  8867.         exec @retcode = @backup_proc
  8868.         if @@error <> 0 or @retcode <> 0
  8869.             goto UNDO
  8870.     end
  8871.  
  8872.     /*
  8873.     ** Prepare the required option
  8874.     */
  8875.     if @proc is not null
  8876.     begin
  8877.         EXEC @retcode = @proc @value = @value,
  8878.             @ignore_distributor = @ignore_distributor
  8879.         IF @@ERROR <> 0 or @retcode <> 0
  8880.         BEGIN
  8881.             GOTO UNDO
  8882.         END
  8883.     end
  8884.  
  8885.  
  8886.     /*
  8887.     ** Preparation succeeded. 
  8888.     ** Toggle the category bit in master..sysdatabases
  8889.     */
  8890.     UPDATE master..sysdatabases SET category = category ^ @optbit
  8891.     WHERE name = @dbname
  8892.     IF @@ERROR <> 0 
  8893.     BEGIN
  8894.         GOTO UNDO
  8895.     END
  8896.  
  8897.  
  8898.     declare @num_mergedb int
  8899.     select @num_mergedb = null
  8900.     if lower(@optname collate SQL_Latin1_General_CP1_CS_AS) = 'merge publish'
  8901.     begin
  8902.         if lower(@value collate SQL_Latin1_General_CP1_CS_AS) = 'true'
  8903.         begin            
  8904.             -- Set the 'startup' option for sp_MScleanupmergepublisher if the
  8905.             -- database is enabled for merge replication.  
  8906.             exec ('use master 
  8907.                    exec dbo.sp_procoption ''sp_MScleanupmergepublisher'', ''startup'', ''true''')
  8908.         end
  8909.         else
  8910.         begin
  8911.             -- Reset the 'startup' option for sp_MScleanupmergepublisher if
  8912.             -- this is the last database that has its 'merge publish' option 
  8913.             -- disabled
  8914.             select @num_mergedb = count(*) from master..sysdatabases 
  8915.              where (category & 4) <> 0
  8916.             if @num_mergedb = 0
  8917.             begin
  8918.                 exec ('use master 
  8919.                        exec dbo.sp_procoption ''sp_MScleanupmergepublisher'', ''startup'', ''false''')
  8920.             end
  8921.         end
  8922.     end
  8923.     
  8924.  
  8925.     -- Get expired subscription cleanup agent name
  8926.     set @agentname = formatmessage(20569)  
  8927.  
  8928.     IF ((LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) = 'merge publish') or (LOWER(@optname) = 'publish')) and (LOWER(@value) = 'true')
  8929.     BEGIN
  8930.         IF NOT EXISTS (SELECT * FROM msdb..sysjobs_view WHERE name = @agentname collate database_default and
  8931.                         UPPER(originating_server) = UPPER(CONVERT(sysname, SERVERPROPERTY('ServerName'))))
  8932.             BEGIN
  8933.                 SELECT @command =  'EXEC dbo.sp_expired_subscription_cleanup'
  8934.             
  8935.                 set @description = formatmessage(20542)
  8936.     
  8937.                 select @category_name = name FROM msdb.dbo.syscategories where category_id = 17   
  8938.                 
  8939.                 EXECUTE @retcode = msdb.dbo.sp_MSadd_repl_job @agentname,
  8940.                 @subsystem = 'TSQL',
  8941.                 @server = @@SERVERNAME,
  8942.                 @databasename = @dbname,
  8943.                 @description = @description,
  8944.                 @freqtype = 4,        -- daily
  8945.                 @activestarttimeofday=010000,   -- from 01:00:00 am
  8946.                 @command = @command,
  8947.                 @enabled = 1,
  8948.                 @retryattempts = 0,
  8949.                 @loghistcompletionlevel = 0,
  8950.                 @category_name = @category_name
  8951.             
  8952.                 IF @@ERROR <> 0 or @retcode <> 0
  8953.                     BEGIN
  8954.                          return (1)
  8955.                     END
  8956.             END
  8957.  
  8958.         -- Expired subscription cleanup alert            
  8959.         select @category_name = name FROM msdb.dbo.syscategories where category_id = 20
  8960.         set @alert_name = formatmessage(20538)  
  8961.         set @alert_id = 14157 -- corresponding to formatmessage(20538)
  8962.         if not exists (select * from msdb.dbo.sysalerts where message_id = @alert_id)
  8963.         begin
  8964.             exec @retcode = msdb.dbo.sp_add_alert @enabled = 0, @name = @alert_name, @category_name = @category_name, @message_id = 14157
  8965.             if @@error <> 0 or @retcode <> 0
  8966.                 goto UNDO
  8967.         end
  8968.     END
  8969.  
  8970.     IF ((LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) = 'merge publish') or (LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) = 'publish')) and (LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) = 'false')
  8971.     BEGIN
  8972.             IF (EXISTS (SELECT * FROM msdb..sysjobs_view WHERE name = @agentname collate database_default and 
  8973.                             UPPER(originating_server) = UPPER(CONVERT(sysname, SERVERPROPERTY('ServerName'))))) 
  8974.                 and (NOT exists (select name from master..sysdatabases where category & 4 =4 ))
  8975.                 and (NOT exists (select name from master..sysdatabases where category & 1 =1))
  8976.         BEGIN
  8977.             EXEC @retcode = msdb.dbo.sp_delete_job  @job_name = @agentname
  8978.             IF @@ERROR <> 0 or @retcode <> 0
  8979.                 return (1)            
  8980.         END
  8981.         
  8982.         set @alert_id = 14157 -- cleanup  alert
  8983.         set @alert_name = formatmessage(20569)
  8984.         if exists (select * from msdb.dbo.sysalerts where message_id=@alert_id)
  8985.             and (NOT exists (select name from master..sysdatabases where category & 4 =4 ))
  8986.                 and (NOT exists (select name from master..sysdatabases where category & 1 =1))
  8987.         begin
  8988.             select @alert_name=name from msdb.dbo.sysalerts where message_id=@alert_id
  8989.             exec @retcode = msdb.dbo.sp_delete_alert @alert_name
  8990.             if @@error <> 0 or @retcode <> 0
  8991.                 return (1)            
  8992.         end
  8993.     END
  8994.     
  8995.     /*
  8996.     **  ??? 
  8997.     ** CHECKPOINT the database that was changed. Make the change
  8998.     ** effective immediatly
  8999.     */
  9000.     CHECKPOINT
  9001.     IF @@ERROR <> 0 
  9002.     BEGIN
  9003.         RETURN(1)
  9004.     END
  9005.  
  9006.     RETURN(0)
  9007.  
  9008. UNDO:
  9009.     -- Create system table is not allowed in a multi-statement transactions.
  9010.     -- Drop the tables here
  9011.     IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) = 'true'
  9012.         EXEC dbo.sp_replicationdboption 
  9013.           @dbname    = @dbname,
  9014.           @optname   = @optname,
  9015.           @value     = 'false',
  9016.           @ignore_distributor = @ignore_distributor
  9017.  
  9018.     return(1)   
  9019. GO
  9020.  
  9021. raiserror('Creating procedure sp_MSfixupdistributorinfo', 0,1)
  9022. go
  9023.  
  9024. CREATE PROCEDURE sp_MSfixupdistributorinfo (
  9025.     @publisher sysname,
  9026.     @publisher_db sysname,
  9027.     @publication sysname,
  9028.     @distributor sysname,
  9029.     @subscription_type int
  9030.     )
  9031. AS
  9032.     DECLARE @local_distributor sysname
  9033.     DECLARE @retcode INT
  9034.  
  9035.     -- If @distributor = @publisher
  9036.     -- we just assume that these values are unspecified 
  9037.     -- and so we inherit these values from other shared subscriptions
  9038.     -- if possible
  9039.     IF @distributor = @publisher
  9040.     BEGIN
  9041.         SELECT TOP 1 @local_distributor = sp.distributor
  9042.           FROM MSsubscription_properties sp
  9043.           JOIN MSreplication_subscriptions rs  
  9044.             ON UPPER(sp.publisher) = UPPER(rs.publisher)
  9045.            AND sp.publisher_db = rs.publisher_db
  9046.            AND rs.subscription_type = @subscription_type
  9047.            AND rs.independent_agent = 0
  9048.          WHERE UPPER(sp.publisher) = UPPER(@publisher)
  9049.            AND sp.publisher_db = @publisher_db
  9050.            AND sp.publication <> @publication
  9051.                       
  9052.         IF @@ROWCOUNT > 0
  9053.         BEGIN
  9054.            -- Inherit the values from other shared subscriptions
  9055.            UPDATE MSsubscription_properties SET 
  9056.             distributor = @local_distributor
  9057.             WHERE UPPER(publisher) = UPPER(@publisher)
  9058.               AND publisher_db = @publisher_db
  9059.               AND publication = @publication
  9060.         END  
  9061.     END
  9062.     ELSE
  9063.     BEGIN
  9064.         EXEC @retcode = sp_MSupdatesharedagentproperties 
  9065.            @publisher = @publisher,
  9066.            @publisher_db = @publisher_db,
  9067.            @publication = @publication,
  9068.            @property = N'distributor',
  9069.            @strvalue = @distributor,
  9070.            @subscription_type = @subscription_type
  9071.         
  9072.         IF @retcode <> 0 OR @@ERROR <> 0
  9073.             GOTO FixupFailure
  9074.                                     
  9075.     END
  9076.  
  9077.     RETURN 0
  9078.  
  9079. FixupFailure:
  9080.     RETURN 1
  9081.  
  9082. GO
  9083.  
  9084. raiserror('Creating procedure sp_MSfixupdistributorsecurity', 0,1)
  9085. go
  9086.  
  9087. CREATE PROCEDURE sp_MSfixupdistributorsecurity (
  9088.     @publisher sysname,
  9089.     @publisher_db sysname,
  9090.     @publication sysname,
  9091.     @distributor_security_mode int, -- default 0 -- standard
  9092.     @distributor_login sysname, -- default 'sa'
  9093.     @distributor_password nvarchar(524), -- default null
  9094.     @subscription_type int
  9095.     )
  9096. AS
  9097.     DECLARE @local_distributor_security_mode int
  9098.     DECLARE @local_distributor_login sysname 
  9099.     DECLARE @local_distributor_password nvarchar(524) 
  9100.     DECLARE @retcode INT
  9101.  
  9102.  
  9103.     IF @distributor_security_mode = 0 AND @distributor_login = 'sa' 
  9104.        AND (@distributor_password IS NULL OR 
  9105.             @distributor_password = N'') 
  9106.     BEGIN
  9107.         -- Parameters are unspecifed, try to inherit values from
  9108.         -- shared susbcriptions
  9109.         SELECT TOP 1 @local_distributor_security_mode = distributor_security_mode,
  9110.                      @local_distributor_login = distributor_login,
  9111.                      @local_distributor_password = distributor_password
  9112.                      FROM MSsubscription_properties sp
  9113.                      JOIN MSreplication_subscriptions rs  
  9114.                        ON UPPER(sp.publisher) = UPPER(rs.publisher)
  9115.                       AND sp.publisher_db = rs.publisher_db
  9116.                       AND rs.subscription_type = @subscription_type
  9117.                       AND rs.independent_agent = 0
  9118.                     WHERE UPPER(sp.publisher) = UPPER(@publisher)
  9119.                       AND sp.publisher_db = @publisher_db
  9120.                       AND sp.publication <> @publication
  9121.         IF @@ROWCOUNT > 0              
  9122.         BEGIN
  9123.            -- Inherit the values from other shared subscriptions
  9124.            UPDATE MSsubscription_properties SET 
  9125.            distributor_security_mode = @local_distributor_security_mode,
  9126.            distributor_login = @local_distributor_login,
  9127.            distributor_password = @local_distributor_password
  9128.             WHERE UPPER(publisher) = UPPER(@publisher)
  9129.               AND publisher_db = @publisher_db
  9130.               AND publication = @publication
  9131.         END  
  9132.     END
  9133.     ELSE
  9134.     BEGIN
  9135.         EXEC @retcode = sp_MSupdatesharedagentproperties 
  9136.            @publisher = @publisher,
  9137.            @publisher_db = @publisher_db,
  9138.            @publication = @publication,
  9139.            @property = N'distributor_security_mode',
  9140.            @intvalue = @distributor_security_mode,
  9141.            @subscription_type = @subscription_type
  9142.         
  9143.         IF @retcode <> 0 OR @@ERROR <> 0
  9144.             GOTO FixupFailure
  9145.                                     
  9146.         EXEC @retcode = sp_MSupdatesharedagentproperties 
  9147.            @publisher = @publisher,
  9148.            @publisher_db = @publisher_db,
  9149.            @publication = @publication,
  9150.            @property = N'distributor_login',
  9151.            @strvalue = @distributor_login,
  9152.            @subscription_type = @subscription_type
  9153.         
  9154.         IF @retcode <> 0 OR @@ERROR <> 0
  9155.             GOTO FixupFailure
  9156.  
  9157.         EXEC @retcode = sp_MSupdatesharedagentproperties 
  9158.            @publisher = @publisher,
  9159.            @publisher_db = @publisher_db,
  9160.            @publication = @publication,
  9161.            @property = N'distributor_password',
  9162.            @strvalue = @distributor_password,
  9163.            @subscription_type = @subscription_type
  9164.         
  9165.         IF @retcode <> 0 OR @@ERROR <> 0
  9166.             GOTO FixupFailure
  9167.     END
  9168.  
  9169.     RETURN 0
  9170.  
  9171. FixupFailure:
  9172.     RETURN 1
  9173.  
  9174. GO
  9175.  
  9176. raiserror('Creating procedure sp_MSfixupftpinfo', 0,1)
  9177. go
  9178.  
  9179. CREATE PROCEDURE sp_MSfixupftpinfo (
  9180.     @publisher sysname,
  9181.     @publisher_db sysname,
  9182.     @publication sysname,
  9183.     @ftp_address sysname,         -- default null
  9184.     @ftp_port int,                -- default null
  9185.     @ftp_login sysname,           -- default null
  9186.     @ftp_password nvarchar(524),  -- default null
  9187.     @subscription_type int,
  9188.     @force_null bit 
  9189.     )
  9190. AS
  9191.     DECLARE @local_ftp_address sysname
  9192.     DECLARE @local_ftp_port sysname 
  9193.     DECLARE @local_ftp_login sysname
  9194.     DECLARE @local_ftp_password nvarchar(524)
  9195.     DECLARE @retcode INT
  9196.  
  9197.     IF @ftp_address IS NULL AND @ftp_port IS NULL AND
  9198.        @ftp_login IS NULL AND @ftp_password IS NULL AND
  9199.        @force_null = 0
  9200.     BEGIN
  9201.         -- Parameters are unspecifed, try to inherit values from
  9202.         -- shared susbcriptions
  9203.         SELECT TOP 1 @local_ftp_address = ftp_address,
  9204.                      @local_ftp_port = ftp_port,
  9205.                      @local_ftp_login = ftp_login,
  9206.                      @local_ftp_password = ftp_password
  9207.           FROM MSsubscription_properties sp
  9208.           JOIN MSreplication_subscriptions rs  
  9209.             ON UPPER(sp.publisher) = UPPER(rs.publisher)
  9210.            AND sp.publisher_db = rs.publisher_db
  9211.            AND rs.subscription_type = @subscription_type
  9212.            AND rs.independent_agent = 0
  9213.          WHERE UPPER(sp.publisher) = UPPER(@publisher)
  9214.            AND sp.publisher_db = @publisher_db
  9215.            AND sp.publication <> @publication
  9216.         IF @@ROWCOUNT > 0              
  9217.         BEGIN
  9218.            -- Inherit the values from other shared subscriptions
  9219.            UPDATE MSsubscription_properties SET 
  9220.             ftp_address = @local_ftp_address,
  9221.             ftp_port = @local_ftp_port,
  9222.             ftp_login = @local_ftp_login,
  9223.             ftp_password = @local_ftp_password
  9224.             WHERE UPPER(publisher) = UPPER(@publisher)
  9225.               AND publisher_db = @publisher_db
  9226.               AND publication = @publication
  9227.         END  
  9228.     END
  9229.     ELSE
  9230.     BEGIN
  9231.         EXEC @retcode = sp_MSupdatesharedagentproperties 
  9232.            @publisher = @publisher,
  9233.            @publisher_db = @publisher_db,
  9234.            @publication = @publication,
  9235.            @property = N'ftp_address',
  9236.            @strvalue = @ftp_address,
  9237.            @subscription_type = @subscription_type
  9238.         
  9239.         IF @retcode <> 0 OR @@ERROR <> 0
  9240.             GOTO FixupFailure
  9241.                                     
  9242.         EXEC @retcode = sp_MSupdatesharedagentproperties 
  9243.            @publisher = @publisher,
  9244.            @publisher_db = @publisher_db,
  9245.            @publication = @publication,
  9246.            @property = N'ftp_port',
  9247.            @intvalue = @ftp_port,
  9248.            @subscription_type = @subscription_type
  9249.         
  9250.         IF @retcode <> 0 OR @@ERROR <> 0
  9251.             GOTO FixupFailure
  9252.  
  9253.         EXEC @retcode = sp_MSupdatesharedagentproperties 
  9254.            @publisher = @publisher,
  9255.            @publisher_db = @publisher_db,
  9256.            @publication = @publication,
  9257.            @property = N'ftp_login',
  9258.            @strvalue = @ftp_login,
  9259.            @subscription_type = @subscription_type
  9260.         
  9261.         IF @retcode <> 0 OR @@ERROR <> 0
  9262.             GOTO FixupFailure
  9263.         EXEC @retcode = sp_MSupdatesharedagentproperties 
  9264.            @publisher = @publisher,
  9265.            @publisher_db = @publisher_db,
  9266.            @publication = @publication,
  9267.            @property = N'ftp_password',
  9268.            @strvalue = @ftp_password,
  9269.            @subscription_type = @subscription_type
  9270.         
  9271.         IF @retcode <> 0 OR @@ERROR <> 0
  9272.             GOTO FixupFailure
  9273.     END
  9274.  
  9275.     RETURN 0
  9276.  
  9277. FixupFailure:
  9278.     RETURN 1
  9279.  
  9280. GO
  9281.  
  9282. raiserror('Creating procedure sp_MSfixupaltsnapshotfolder', 0,1)
  9283. go
  9284.  
  9285. CREATE PROCEDURE sp_MSfixupaltsnapshotfolder (
  9286.     @publisher sysname,
  9287.     @publisher_db sysname,
  9288.     @publication sysname,
  9289.     @alt_snapshot_folder nvarchar(255), -- default null
  9290.     @subscription_type int,
  9291.     @force_null bit 
  9292.     )
  9293. AS
  9294.  
  9295.     DECLARE @local_alt_snapshot_folder sysname 
  9296.     DECLARE @retcode INT
  9297.  
  9298.     IF @alt_snapshot_folder IS NULL AND @force_null = 0
  9299.     BEGIN
  9300.         -- Parameter is unspecifed, try to inherit value from
  9301.         -- shared susbcriptions
  9302.         SELECT TOP 1 @local_alt_snapshot_folder = alt_snapshot_folder
  9303.           FROM MSsubscription_properties sp
  9304.           JOIN MSreplication_subscriptions rs  
  9305.             ON UPPER(sp.publisher) = UPPER(rs.publisher)
  9306.            AND sp.publisher_db = rs.publisher_db
  9307.            AND rs.subscription_type = @subscription_type
  9308.            AND rs.independent_agent = 0
  9309.          WHERE UPPER(sp.publisher) = UPPER(@publisher)
  9310.            AND sp.publisher_db = @publisher_db
  9311.            AND sp.publication <> @publication
  9312.         IF @@ROWCOUNT > 0           
  9313.         BEGIN
  9314.            -- Inherit the values from other shared subscriptions
  9315.            UPDATE MSsubscription_properties SET 
  9316.             alt_snapshot_folder = @local_alt_snapshot_folder
  9317.             WHERE UPPER(publisher) = UPPER(@publisher)
  9318.               AND publisher_db = @publisher_db
  9319.               AND publication = @publication
  9320.         END  
  9321.     END
  9322.     ELSE
  9323.     BEGIN
  9324.         EXEC @retcode = sp_MSupdatesharedagentproperties 
  9325.            @publisher = @publisher,
  9326.            @publisher_db = @publisher_db,
  9327.            @publication = @publication,
  9328.            @property = N'alt_snapshot_folder',
  9329.            @strvalue = @alt_snapshot_folder,
  9330.            @subscription_type = @subscription_type
  9331.         
  9332.         IF @retcode <> 0 OR @@ERROR <> 0
  9333.             GOTO FixupFailure                                    
  9334.     END
  9335.  
  9336.     RETURN 0
  9337.  
  9338. FixupFailure:
  9339.     RETURN 1
  9340.  
  9341. GO
  9342.  
  9343. raiserror('Creating procedure sp_MSfixupworkingdirectory', 0,1)
  9344. go
  9345.  
  9346. CREATE PROCEDURE sp_MSfixupworkingdirectory (
  9347.     @publisher sysname,
  9348.     @publisher_db sysname,
  9349.     @publication sysname,
  9350.     @working_directory nvarchar(255), -- default null
  9351.     @subscription_type int
  9352.     )
  9353. AS
  9354.  
  9355.     DECLARE @local_working_directory sysname 
  9356.     DECLARE @retcode INT
  9357.  
  9358.     IF @working_directory IS NULL
  9359.     BEGIN
  9360.         -- Parameter is unspecifed, try to inherit value from
  9361.         -- shared susbcriptions
  9362.         SELECT TOP 1 @local_working_directory = working_directory
  9363.           FROM MSsubscription_properties sp
  9364.           JOIN MSreplication_subscriptions rs  
  9365.             ON UPPER(sp.publisher) = UPPER(rs.publisher)
  9366.            AND sp.publisher_db = rs.publisher_db
  9367.            AND rs.subscription_type = @subscription_type
  9368.            AND rs.independent_agent = 0
  9369.          WHERE UPPER(sp.publisher) = UPPER(@publisher)
  9370.            AND sp.publisher_db = @publisher_db
  9371.            AND sp.publication <> @publication
  9372.         IF @@ROWCOUNT > 0           
  9373.         BEGIN
  9374.            -- Inherit the values from other shared subscriptions
  9375.            UPDATE MSsubscription_properties SET 
  9376.             working_directory = @local_working_directory
  9377.             WHERE UPPER(publisher) = UPPER(@publisher)
  9378.               AND publisher_db = @publisher_db
  9379.               AND publication = @publication
  9380.         END  
  9381.     END
  9382.     ELSE
  9383.     BEGIN
  9384.         EXEC @retcode = sp_MSupdatesharedagentproperties 
  9385.            @publisher = @publisher,
  9386.            @publisher_db = @publisher_db,
  9387.            @publication = @publication,
  9388.            @property = N'working_directory',
  9389.            @strvalue = @working_directory,
  9390.            @subscription_type = @subscription_type
  9391.         
  9392.         IF @retcode <> 0 OR @@ERROR <> 0
  9393.             GOTO FixupFailure                                    
  9394.     END
  9395.  
  9396.     RETURN 0
  9397.  
  9398. FixupFailure:
  9399.     RETURN 1
  9400.  
  9401. GO
  9402.  
  9403. raiserror('Creating procedure sp_MSfixupuseftp', 0,1)
  9404. go
  9405.  
  9406. CREATE PROCEDURE sp_MSfixupuseftp (
  9407.     @publisher sysname,
  9408.     @publisher_db sysname,
  9409.     @publication sysname,
  9410.     @use_ftp bit, -- default null
  9411.     @subscription_type int,
  9412.     @force_zero bit
  9413.     )
  9414. AS
  9415.  
  9416.     DECLARE @local_use_ftp bit
  9417.     DECLARE @retcode INT
  9418.  
  9419.     IF @use_ftp = 0 AND @force_zero = 0
  9420.     BEGIN
  9421.         -- Parameter is unspecifed, try to inherit value from
  9422.         -- shared susbcriptions
  9423.         SELECT TOP 1 @local_use_ftp = use_ftp
  9424.           FROM MSsubscription_properties sp
  9425.           JOIN MSreplication_subscriptions rs  
  9426.             ON UPPER(sp.publisher) = UPPER(rs.publisher)
  9427.            AND sp.publisher_db = rs.publisher_db
  9428.            AND rs.subscription_type = @subscription_type
  9429.            AND rs.independent_agent = 0
  9430.          WHERE UPPER(sp.publisher) = UPPER(@publisher)
  9431.            AND sp.publisher_db = @publisher_db
  9432.            AND sp.publication <> @publication
  9433.         IF @@ROWCOUNT > 0           
  9434.         BEGIN
  9435.            -- Inherit the values from other shared subscriptions
  9436.            UPDATE MSsubscription_properties SET 
  9437.             use_ftp = @local_use_ftp
  9438.             WHERE UPPER(publisher) = UPPER(@publisher)
  9439.               AND publisher_db = @publisher_db
  9440.               AND publication = @publication
  9441.         END  
  9442.     END
  9443.     ELSE
  9444.     BEGIN
  9445.         EXEC @retcode = sp_MSupdatesharedagentproperties 
  9446.            @publisher = @publisher,
  9447.            @publisher_db = @publisher_db,
  9448.            @publication = @publication,
  9449.            @property = N'use_ftp',
  9450.            @intvalue = @use_ftp,
  9451.            @subscription_type = @subscription_type
  9452.         
  9453.         IF @retcode <> 0 OR @@ERROR <> 0
  9454.             GOTO FixupFailure                                    
  9455.     END
  9456.  
  9457.     RETURN 0
  9458.  
  9459. FixupFailure:
  9460.     RETURN 1
  9461.  
  9462. GO
  9463.  
  9464. raiserror('Creating procedure sp_MSfixup_offload_agent_info', 0,1)
  9465. go
  9466.  
  9467. CREATE PROCEDURE sp_MSfixupagentoffloadinfo (
  9468.     @publisher sysname,
  9469.     @publisher_db sysname,
  9470.     @publication sysname,
  9471.     @distributor sysname,
  9472.     @offload_agent bit, -- default 0
  9473.     @offload_server sysname, -- default null
  9474.     @subscription_type int
  9475.     )
  9476. AS
  9477.     DECLARE @local_offload_agent bit
  9478.     DECLARE @local_offload_server sysname
  9479.     DECLARE @retcode INT
  9480.  
  9481.     IF @offload_agent = 0 AND 
  9482.         @offload_server is null
  9483.     BEGIN
  9484.         -- Parameters are assumed to be be unspecified, try to inherit values 
  9485.         -- from shared subscriptions
  9486.         SELECT TOP 1 @local_offload_agent = offload_agent,
  9487.                      @local_offload_server = offload_server
  9488.           FROM MSsubscription_properties sp
  9489.           JOIN MSreplication_subscriptions rs
  9490.             ON UPPER(sp.publisher) = UPPER(rs.publisher)
  9491.            AND sp.publisher_db = rs.publisher_db
  9492.            AND rs.subscription_type = @subscription_type
  9493.            AND rs.independent_agent = 0
  9494.          WHERE UPPER(sp.publisher) = UPPER(@publisher)
  9495.            AND sp.publisher_db = @publisher_db
  9496.            AND sp.publication <> @publication
  9497.         IF @@ROWCOUNT > 0
  9498.         BEGIN
  9499.             -- Inherit the values from other shared subscriptions
  9500.             UPDATE MSsubscription_properties SET
  9501.              offload_agent = @local_offload_agent,
  9502.              offload_server = @local_offload_server
  9503.             WHERE UPPER(publisher) = UPPER(@publisher)
  9504.               AND publisher_db = @publisher_db
  9505.               AND publication = @publication
  9506.         END
  9507.     END
  9508.     ELSE
  9509.     BEGIN
  9510.         EXEC @retcode = sp_MSupdatesharedagentproperties
  9511.             @publisher = @publisher,
  9512.             @publisher_db = @publisher_db,
  9513.             @publication = @publication,
  9514.             @property = N'offload_agent',
  9515.             @intvalue = @offload_agent,
  9516.             @subscription_type = @subscription_type
  9517.  
  9518.         IF @retcode <> 0 OR @@ERROR <> 0
  9519.             GOTO FixupFailure
  9520.         
  9521.         EXEC @retcode = sp_MSupdatesharedagentproperties
  9522.             @publisher = @publisher,
  9523.             @publisher_db = @publisher_db,
  9524.             @publication = @publication,
  9525.             @property = N'offload_server',
  9526.             @strvalue = @offload_server,
  9527.             @subscription_type = @subscription_type
  9528.     END
  9529.              
  9530.     RETURN 0
  9531.  
  9532. FixupFailure:
  9533.     RETURN 1
  9534.  
  9535. GO
  9536.  
  9537. raiserror('Creating procedure sp_MSfixupsharedagentproperties', 0,1)
  9538. go
  9539.  
  9540. CREATE PROCEDURE sp_MSfixupsharedagentproperties (
  9541.     @publisher sysname,
  9542.     @publisher_db sysname,
  9543.     @publication sysname,         /* publication name */
  9544.     @distributor sysname,       -- default @publisher
  9545.     @distributor_security_mode int, -- default 0 -- standard
  9546.     @distributor_login sysname, -- default 'sa'
  9547.     @distributor_password nvarchar(524), -- default null
  9548.     @ftp_address sysname,       -- default null
  9549.     @ftp_port int,              -- default null
  9550.     @ftp_login sysname,         -- default null
  9551.     @ftp_password nvarchar(524),      -- default null
  9552.     @alt_snapshot_folder nvarchar(255), -- default null
  9553.     @working_directory   nvarchar(255), -- default null
  9554.     @use_ftp bit,               -- default 0
  9555.     @offload_agent bit,         -- default 0
  9556.     @offload_server sysname     -- default @distributor
  9557.     )
  9558. AS
  9559.     DECLARE @subscription_type int
  9560.     DECLARE @retcode int
  9561.     DECLARE @force_ftp_null bit
  9562.     DECLARE @force_alt_snapshot_folder_null bit
  9563.  
  9564.     IF @alt_snapshot_folder IS NOT NULL AND @alt_snapshot_folder <> N''
  9565.         SELECT @force_ftp_null = 1 
  9566.     ELSE
  9567.         SELECT @force_ftp_null = 0 
  9568.  
  9569.     IF (@use_ftp = 1)  OR (@ftp_address IS NOT NULL AND @ftp_address <> N'')
  9570.         SELECT @force_alt_snapshot_folder_null = 1 
  9571.     ELSE
  9572.         SELECT @force_alt_snapshot_folder_null = 0 
  9573.         
  9574.     SELECT @subscription_type = subscription_type
  9575.       FROM MSreplication_subscriptions 
  9576.      WHERE UPPER(publisher) = UPPER(@publisher)
  9577.        AND publisher_db = @publisher_db
  9578.        AND publication = @publication
  9579.     -- No need to fix up the publisher security properties 
  9580.     -- because they are defined on a per subscription 
  9581.     -- basis for SyncTran
  9582.  
  9583.     EXEC @retcode = sp_MSfixupdistributorinfo
  9584.         @publisher = @publisher,
  9585.         @publisher_db = @publisher_db,
  9586.         @publication = @publication,
  9587.         @distributor = @distributor,
  9588.         @subscription_type = @subscription_type
  9589.  
  9590.     IF @@ERROR <> 0 OR @retcode <> 0
  9591.         GOTO FixupFailure
  9592.  
  9593.     EXEC @retcode = sp_MSfixupdistributorsecurity 
  9594.         @publisher = @publisher,
  9595.         @publisher_db = @publisher_db,
  9596.         @publication = @publication,
  9597.         @distributor_login = @distributor_login,
  9598.         @distributor_password = @distributor_password,
  9599.         @distributor_security_mode = @distributor_security_mode,                            
  9600.         @subscription_type = @subscription_type
  9601.  
  9602.     IF @@ERROR <> 0 OR @retcode <> 0
  9603.         GOTO FixupFailure
  9604.  
  9605. /* Ignore ftp_address, ftp_port, ftp_login, ftp_password on post 7.0 server
  9606.     EXEC @retcode = sp_MSfixupftpinfo
  9607.         @publisher = @publisher,
  9608.         @publisher_db = @publisher_db,
  9609.         @publication = @publication,
  9610.         @ftp_address = @ftp_address,
  9611.         @ftp_port = @ftp_port,
  9612.         @ftp_login = @ftp_login,
  9613.         @ftp_password = @ftp_password,
  9614.         @subscription_type = @subscription_type,
  9615.         @force_null = @force_ftp_null
  9616.  
  9617.     IF @@ERROR <> 0 OR @retcode <> 0
  9618.         GOTO FixupFailure
  9619. */
  9620.     EXEC @retcode = sp_MSfixupaltsnapshotfolder
  9621.         @publisher = @publisher,
  9622.         @publisher_db = @publisher_db,
  9623.         @publication = @publication,
  9624.         @alt_snapshot_folder = @alt_snapshot_folder,
  9625.         @subscription_type = @subscription_type,
  9626.         @force_null = @force_alt_snapshot_folder_null
  9627.  
  9628.     IF @@ERROR <> 0 OR @retcode <> 0
  9629.         GOTO FixupFailure
  9630.  
  9631.     EXEC @retcode = sp_MSfixupworkingdirectory
  9632.         @publisher = @publisher,
  9633.         @publisher_db = @publisher_db,
  9634.         @publication = @publication,
  9635.         @working_directory = @working_directory,
  9636.         @subscription_type = @subscription_type
  9637.  
  9638.     IF @@ERROR <> 0 OR @retcode <> 0
  9639.         GOTO FixupFailure
  9640.  
  9641.     EXEC @retcode = sp_MSfixupuseftp
  9642.         @publisher = @publisher,
  9643.         @publisher_db = @publisher_db,
  9644.         @publication = @publication,
  9645.         @use_ftp = @use_ftp,
  9646.         @subscription_type = @subscription_type,
  9647.         @force_zero = @force_ftp_null
  9648.  
  9649.     IF @@ERROR <> 0 OR @retcode <> 0
  9650.         GOTO FixupFailure
  9651.  
  9652.     EXEC @retcode = sp_MSfixupagentoffloadinfo
  9653.         @publisher = @publisher,
  9654.         @publisher_db = @publisher_db,
  9655.         @publication = @publication,
  9656.         @distributor = @distributor,
  9657.         @offload_agent = @offload_agent,
  9658.         @offload_server = @offload_server,
  9659.         @subscription_type = @subscription_type
  9660.  
  9661.     IF @@ERROR <> 0 OR @retcode <> 0
  9662.         GOTO FixupFailure
  9663.  
  9664.     RETURN 0
  9665.  
  9666. FixupFailure:
  9667.  
  9668.     RETURN 1
  9669.  
  9670. GO
  9671.  
  9672. raiserror('Creating procedure sp_addpullsubscription_agent', 0,1)
  9673. go
  9674.  
  9675. CREATE PROCEDURE sp_addpullsubscription_agent (
  9676.     @publisher sysname,
  9677.     @publisher_db sysname,
  9678.     @publication sysname,         /* publication name */
  9679.     @subscriber sysname = NULL,
  9680.     @subscriber_db sysname = NULL,
  9681.     @subscriber_security_mode       int = NULL,                     /* 0 standard; 1 integrated */
  9682.     @subscriber_login               sysname = NULL,
  9683.     @subscriber_password            sysname = NULL,
  9684.     @distributor sysname = @publisher,
  9685.     @distribution_db sysname = NULL,
  9686.     @distributor_security_mode int = 0,
  9687.     @distributor_login sysname = 'sa',
  9688.     @distributor_password sysname = NULL,
  9689.     @optional_command_line nvarchar(4000) = '',
  9690.     @frequency_type  int = 2 ,  /* 2== OnDemand */
  9691.     @frequency_interval int = 1, 
  9692.     @frequency_relative_interval int = 1, 
  9693.     @frequency_recurrence_factor int = 1, 
  9694.     @frequency_subday int = 1, 
  9695.     @frequency_subday_interval int = 1 ,
  9696.     @active_start_time_of_day int = 0, 
  9697.     @active_end_time_of_day int = 0,         
  9698.     @active_start_date int = 0, 
  9699.     @active_end_date int =0,
  9700.     @distribution_jobid binary(16) = NULL OUTPUT,
  9701.     @encrypted_distributor_password bit = 0,
  9702.     @enabled_for_syncmgr nvarchar(5) = 'false', /* Enabled for SYNCMGR: true or false */
  9703.     @ftp_address sysname = NULL,
  9704.     @ftp_port int = NULL,
  9705.     @ftp_login sysname = NULL,
  9706.     @ftp_password sysname = NULL,
  9707.     @alt_snapshot_folder  nvarchar(255) = NULL,
  9708.     @working_directory    nvarchar(255) = NULL,
  9709.     @use_ftp              nvarchar(5) = 'false',
  9710.     @publication_type     tinyint = 0,-- 0 - Transactional, 1 - Snapshot, 2 - Merge
  9711.     @dts_package_name sysname  = NULL,  /* value will be sent and validated at distributor */                                  
  9712.     @dts_package_password  sysname = NULL,
  9713.     @dts_package_location nvarchar(12) = N'subscriber',
  9714.     @reserved nvarchar(100) = N'', -- Not default to null because null problems in conditional expressions.
  9715.     @offloadagent          nvarchar(5) = 'false',
  9716.     @offloadserver         sysname = NULL,
  9717.     @job_name              sysname = NULL
  9718.     ) AS
  9719.  
  9720.     SET NOCOUNT ON
  9721.  
  9722.     /*
  9723.     ** Declarations.
  9724.     */
  9725.  
  9726.     DECLARE @command nvarchar(4000)
  9727.     DECLARE @retcode int
  9728.     DECLARE @subscription_type_id int   /* 1 = pull, 2 = anonymous */
  9729.     DECLARE @independent_agent_id bit
  9730.     DECLARE @distribution_agent nvarchar(100) 
  9731.     DECLARE @category_name sysname
  9732.     DECLARE @platform_nt binary
  9733.     DECLARE @subscriber_enc_password nvarchar(524)
  9734.     DECLARE @distributor_enc_password   nvarchar(524)
  9735.     DECLARE @use_ftp_bit bit
  9736.     DECLARE @offload_agent_bit bit
  9737.     
  9738.     select @platform_nt = 0x1
  9739.  
  9740.     /*
  9741.     ** Security Check
  9742.     */
  9743.  
  9744.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  9745.     IF @@ERROR <> 0 or @retcode <> 0
  9746.         RETURN(1)
  9747.  
  9748.     /*
  9749.     ** Initializations.
  9750.     */
  9751.  
  9752.     -- Set null @optional_command_line to empty string to avoid string concat problem
  9753.     if @optional_command_line is null
  9754.         set @optional_command_line = ''
  9755.     else
  9756.         set @optional_command_line = N' ' + LTRIM( RTRIM(@optional_command_line) ) + N' '
  9757.  
  9758.     IF @distributor_password = N''
  9759.         select @distributor_password = NULL
  9760.  
  9761.     IF @ftp_password = N''
  9762.         select @ftp_password = NULL
  9763.  
  9764.     IF @dts_package_password = N''
  9765.         select @dts_package_password = NULL
  9766.  
  9767.     /*
  9768.     ** Parameter Check: @publisher
  9769.     ** Check to make sure that the publisher is define
  9770.     */
  9771.     IF @publisher IS NULL
  9772.     BEGIN
  9773.         RAISERROR (14043, 16, -1, '@publisher')
  9774.         RETURN (1)
  9775.     END
  9776.  
  9777.     EXECUTE @retcode = dbo.sp_validname @publisher
  9778.  
  9779.     IF @@ERROR <> 0 OR @retcode <> 0
  9780.        RETURN (1)
  9781.     
  9782.  
  9783.     /*
  9784.     ** Parameter Check: @publisher_db
  9785.     */
  9786.  
  9787.     IF @publisher_db IS NULL
  9788.     BEGIN
  9789.         RAISERROR (14043, 16, -1, '@publisher_db')
  9790.         RETURN (1)
  9791.     END
  9792.  
  9793.     EXECUTE @retcode = dbo.sp_validname @publisher_db
  9794.  
  9795.     IF @@ERROR <> 0 OR @retcode <> 0
  9796.        RETURN (1)
  9797.  
  9798.     /*
  9799.     ** Parameter Check: @publication
  9800.     ** 
  9801.     */
  9802.     IF @publication IS NULL
  9803.     BEGIN
  9804.         RAISERROR (14043, 16, -1, '@publication')
  9805.         RETURN (1)
  9806.     END
  9807.  
  9808.     EXECUTE @retcode = dbo.sp_validname @publication
  9809.  
  9810.     IF @@ERROR <> 0 OR @retcode <> 0
  9811.        RETURN (1)
  9812.  
  9813.     /*
  9814.     ** Parameter Check: @subscriber and @subscriber_db
  9815.     */
  9816.  
  9817.     if @subscriber IS NULL or rtrim(@subscriber) = ''
  9818.         SELECT @subscriber = @@SERVERNAME
  9819.  
  9820.     if @subscriber_db IS NULL or rtrim(@subscriber_db) = ''
  9821.         SELECT @subscriber_db = DB_NAME()
  9822.     
  9823.     EXECUTE @retcode = dbo.sp_validname @subscriber
  9824.     IF @@ERROR <> 0 OR @retcode <> 0
  9825.        RETURN (1)
  9826.     
  9827.     EXECUTE @retcode = dbo.sp_validname @subscriber_db
  9828.     IF @@ERROR <> 0 OR @retcode <> 0
  9829.        RETURN (1)
  9830.  
  9831.     /* 
  9832.     ** Check to see if MSreplictaion_subscriptions table exists.
  9833.     ** If so, copy it into the temp table
  9834.     */
  9835.     IF  NOT EXISTS (SELECT * FROM sysobjects WHERE 
  9836.         type = 'U' AND
  9837.         name = 'MSreplication_subscriptions')
  9838.     BEGIN
  9839.         RAISERROR (20017, 16, -1)
  9840.         RETURN (1)
  9841.     END 
  9842.     
  9843.     /*
  9844.     ** Check to make sure that the subscription does exist
  9845.     */
  9846.     IF NOT EXISTS (SELECT * FROM  MSreplication_subscriptions
  9847.                 WHERE UPPER(publisher) = UPPER(@publisher) AND
  9848.                       publisher_db  = @publisher_db AND
  9849.                       publication = @publication)
  9850.     BEGIN
  9851.         RAISERROR (20017, 16, -1)
  9852.         RETURN (1)
  9853.     END
  9854.     
  9855.     declare @update_mode_id int
  9856.     SELECT  @distribution_agent = NULL
  9857.     SELECT  @independent_agent_id = independent_agent, 
  9858.             @subscription_type_id = subscription_type,
  9859.             @distribution_agent = distribution_agent,
  9860.             @update_mode_id = update_mode
  9861.         FROM  MSreplication_subscriptions
  9862.         WHERE UPPER(publisher) = UPPER(@publisher) AND
  9863.               publisher_db  = @publisher_db AND
  9864.               publication = @publication
  9865.     /* Distribution agent for push subscriptions is at distributor side */
  9866.     IF @subscription_type_id = 0
  9867.     BEGIN
  9868.         RAISERROR (21001, 16, -1)
  9869.         RETURN (1)
  9870.     END
  9871.  
  9872.     IF @distribution_agent IS NOT NULL
  9873.     BEGIN
  9874.         RAISERROR (21002, 11, -1, @distribution_agent)
  9875.         RETURN (1)
  9876.     END
  9877.  
  9878.     -- Parameter check: @subscriber_security_mode
  9879.     if @subscriber_security_mode is null
  9880.     begin
  9881.         if ( platform() & @platform_nt ) = @platform_nt
  9882.             select @subscriber_security_mode = 1
  9883.         else
  9884.             select @subscriber_security_mode = 0
  9885.     end 
  9886.  
  9887.     if ( ( platform() & @platform_nt ) <> @platform_nt and @subscriber_security_mode = 1 )
  9888.     begin
  9889.         RAISERROR(21038, 16, -1)
  9890.         RETURN (1)
  9891.     end
  9892.  
  9893.     if (@subscription_type_id <> 0)
  9894.     begin
  9895.         if (@subscriber_security_mode = 0) and (@subscriber_login IS NULL or rtrim(@subscriber_login) = '')
  9896.         begin
  9897.             raiserror(21344, 16, -1, '@subscriber_login')
  9898.             return (1)
  9899.         end
  9900.     end
  9901.     
  9902.     if (@distributor_security_mode = 0) and (@distributor_login IS NULL or rtrim(@distributor_login) = '')
  9903.     begin
  9904.         raiserror(3217, 16, -1, '@distributor_login')
  9905.         return (1)
  9906.     end
  9907.  
  9908.     IF NOT EXISTS (select * from sysobjects where name = 'MSsubscription_properties' and type = 'U')
  9909.     begin
  9910.         exec @retcode = sp_MScreate_sub_tables @property_table = 1
  9911.         if @retcode <> 0 or @@error <> 0
  9912.         return (1)
  9913.     end
  9914.  
  9915.     /* 
  9916.     ** Parameter check: @alt_snapshot_folder 
  9917.     ** @alt_snapshot_folder and @use_ftp are mutually exclusive    
  9918.     */
  9919.  
  9920.     IF @alt_snapshot_folder <> N'' AND @alt_snapshot_folder IS NOT NULL
  9921.        AND LOWER(@use_ftp collate SQL_Latin1_General_CP1_CS_AS) = N'true'
  9922.     BEGIN
  9923.         RAISERROR(21146, 16, -1)
  9924.         RETURN (1)
  9925.     END
  9926.  
  9927.     /* 
  9928.     ** Parameter check: @use_ftp
  9929.     ** Must be 'true' or 'false'
  9930.     */
  9931.     IF LOWER(@use_ftp collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('true', 'false')
  9932.     BEGIN
  9933.         RAISERROR (14148, 16, -1, '@use_ftp')
  9934.         RETURN (1)
  9935.     END
  9936.     
  9937.     IF LOWER(@use_ftp collate SQL_Latin1_General_CP1_CS_AS) = 'true'
  9938.     BEGIN
  9939.         SELECT @use_ftp_bit = 1
  9940.     END
  9941.     ELSE
  9942.     BEGIN
  9943.         SELECT @use_ftp_bit = 0
  9944.     END
  9945.  
  9946.  
  9947.     /*
  9948.     ** Parameter check: @publication_type
  9949.     ** Must be 0 - Transactional or 1 - Snapshot
  9950.     */
  9951.     IF @publication_type NOT IN (0, 1)
  9952.     BEGIN
  9953.         RAISERROR (20033, 16, -1)
  9954.         RETURN (1)
  9955.     END
  9956.  
  9957.     /*
  9958.     ** Parameter Check: @dts_package_location
  9959.     ** Valid values:
  9960.     ** distributor
  9961.     ** subscriber
  9962.     **
  9963.     */
  9964.     IF LOWER(@dts_package_location collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('distributor', 'subscriber')
  9965.     BEGIN
  9966.         RAISERROR(21179, 16, -1)    
  9967.         RETURN (1)
  9968.     END
  9969.  
  9970.     declare @dts_package_location_id int
  9971.  
  9972.     IF LOWER(@dts_package_location collate SQL_Latin1_General_CP1_CS_AS) = 'distributor'
  9973.         SELECT @dts_package_location_id = 0
  9974.     ELSE 
  9975.         SELECT @dts_package_location_id = 1
  9976.  
  9977.     -- Have to be a push, non updatable  subscription to set DTS package name
  9978.     if @dts_package_name is not null
  9979.     begin
  9980.         if  @update_mode_id != 0
  9981.         begin
  9982.             RAISERROR(21180, 16, -1)    
  9983.             RETURN (1)
  9984.         end
  9985.     end
  9986.     
  9987.     -- Copy the passwords to new value before attempting to encrypt
  9988.     set @distributor_enc_password = @distributor_password
  9989.     IF (@encrypted_distributor_password = 0)
  9990.         -- Encrypt the password
  9991.         BEGIN
  9992.             EXEC @retcode = master.dbo.xp_repl_encrypt @distributor_enc_password OUTPUT
  9993.             IF @@error <> 0 OR @retcode <> 0
  9994.                 return 1
  9995.         END
  9996.     
  9997.     declare @dts_package_enc_password nvarchar(524)
  9998.     set @dts_package_enc_password = @dts_package_password
  9999.  
  10000.     if @dts_package_enc_password is not null
  10001.     begin
  10002.         EXEC @retcode = master.dbo.xp_repl_encrypt @dts_package_enc_password OUTPUT
  10003.         IF @@error <> 0 OR @retcode <> 0
  10004.             return 1
  10005.     end
  10006.  
  10007.     /*
  10008.     ** Parameter Check: @offloadserver
  10009.     ** 1. If @offloadagent = 'true' then @offloadserver cannot be null.
  10010.     ** 2. Similar to the push case, we don't allow "remote" activation
  10011.     **    of agent on the local machine.
  10012.     */
  10013.     SELECT @offloadagent = LOWER(@offloadagent collate SQL_Latin1_General_CP1_CS_AS)
  10014.     IF @offloadagent NOT IN ('true', 'false')
  10015.     BEGIN
  10016.         RAISERROR (14148, 16, -1, '@offloadagent')
  10017.         RETURN (1)
  10018.     END
  10019.  
  10020.     IF @offloadagent = 'true'
  10021.     BEGIN
  10022.         SELECT @offload_agent_bit = 1
  10023.     END
  10024.     ELSE
  10025.     BEGIN
  10026.         SELECT @offload_agent_bit = 0
  10027.     END
  10028.  
  10029.     IF @offload_agent_bit = 1 AND (@offloadserver is NULL or
  10030.                                @offloadserver = N'')
  10031.     BEGIN
  10032.         RAISERROR(21215, 16, -1)
  10033.         RETURN (1)
  10034.     END
  10035.     
  10036.     IF UPPER(@offloadserver) = UPPER(@@SERVERNAME) AND
  10037.        @offload_agent_bit = 1
  10038.     BEGIN
  10039.         RAISERROR(21227, 16, -1)
  10040.         RETURN (1)
  10041.     END
  10042.  
  10043.     EXEC @retcode = sp_MSreplcheckoffloadserver @offloadserver
  10044.     IF @retcode <> 0 OR @@ERROR <> 0
  10045.         RETURN (1)
  10046.  
  10047.     /*
  10048.     ** Construct unique name
  10049.     */
  10050.     if @subscriber is NULL select @subscriber = ''
  10051.     if @subscriber_db is NULL select @subscriber_db = ''
  10052.     
  10053.     declare @job_existing bit
  10054.     if @job_name is null
  10055.     begin
  10056.         select @job_existing = 0
  10057.         SELECT @job_name = CONVERT(nvarchar(18),@publisher ) + '-' + CONVERT(nvarchar(18),@publisher_db) + '-' + 
  10058.                         CONVERT(nvarchar(18),@publication) + '-' + CONVERT(nvarchar(18),@subscriber) + '-' +
  10059.                         CONVERT(nvarchar(18),@subscriber_db) + '-' + CONVERT(nvarchar(36),newid())
  10060.     end
  10061.     else
  10062.         select @job_existing = 1
  10063.  
  10064.     -- Get property values.
  10065.     if @reserved = 'no_change_to_properties'
  10066.     begin
  10067.         -- Get the distributor value. It will be used in agent command line.
  10068.         select @distributor = distributor, 
  10069.             @enabled_for_syncmgr = case enabled_for_syncmgr
  10070.                 when 0 then 'false'
  10071.                 when 1 then 'true'
  10072.                 end
  10073.         from MSsubscription_properties where
  10074.             UPPER(publisher) = UPPER(@publisher)
  10075.             and publisher_db =  @publisher_db
  10076.             and publication = @publication              
  10077.     end
  10078.  
  10079.     BEGIN TRAN
  10080.  
  10081.     /*
  10082.     ** If the publication is independent agent type or it is the first
  10083.     ** subscription on the non independent agent publications.
  10084.     */
  10085.  
  10086.     IF @independent_agent_id = 1 OR 
  10087.         NOT EXISTS (SELECT * FROM MSreplication_subscriptions WHERE
  10088.                             UPPER(@publisher) = UPPER(publisher) and
  10089.                             @publisher_db = publisher_db and
  10090.                             agent_id IS NOT NULL and
  10091.                             independent_agent = 0)
  10092.     BEGIN
  10093.         if @job_existing = 0
  10094.         begin
  10095.             /* Construct agent command */
  10096.             SELECT @command = '-Publisher ' + @publisher + ' '
  10097.             SELECT @command = @command + '-PublisherDB ' + QUOTENAME(@publisher_db) + ' '
  10098.             IF @independent_agent_id = 1
  10099.                 SELECT @command = @command + '-Publication ' + QUOTENAME(@publication) + ' '
  10100.  
  10101.             SELECT @command = @command + '-Distributor ' + QUOTENAME(@distributor)  + ' '
  10102.  
  10103.             /*
  10104.             Use -Xdatabase to save command line space
  10105.             We can not use -Xserver for distribution because SQLExec will validate the server
  10106.             to be in sysservers.
  10107.  
  10108.             SELECT @command = @command + '-DistributionDB ' + QUOTENAME(@distribution_db)  + ' '
  10109.             */
  10110.             
  10111.             SELECT @command = @command + '-SubscriptionType ' + convert(nvarchar(10),@subscription_type_id)  + ' '
  10112.             SELECT @command = @command + '-Subscriber ' + QUOTENAME(@subscriber)  + ' '
  10113.         
  10114.             select @command = @command + '-SubscriberSecurityMode ' + 
  10115.                 convert(nvarchar(10),@subscriber_security_mode) + ' '
  10116.             if @subscriber_login is not NULL
  10117.                 select @command = @command + '-SubscriberLogin ' + quotename(@subscriber_login) + ' '
  10118.             if @subscriber_password is not NULL
  10119.             begin
  10120.                 set @subscriber_enc_password = @subscriber_password
  10121.                 exec @retcode = master.dbo.xp_repl_encrypt @subscriber_enc_password OUTPUT
  10122.                 select @command = @command + '-SubscriberEncryptedPassword ' + quotename(@subscriber_enc_password) + ' '
  10123.             end
  10124.  
  10125.             SELECT @command = @command + '-SubscriberDB ' + QUOTENAME(@subscriber_db) + ' '
  10126.  
  10127.                     
  10128.             if @dts_package_name is not null
  10129.               select @command = @command + '-UseDTS '
  10130.  
  10131.             if @offload_agent_bit = 1 
  10132.                 select @command = @command + N'-Offload ' + @offloadserver + N' '
  10133.  
  10134.             /* 
  10135.             ** make sure the command line is not truncated
  10136.             */
  10137.             /* Use datalength because len doesn't count the last space in @command */
  10138.             IF (datalength(@command) + datalength(@optional_command_line)) > 8000
  10139.             BEGIN
  10140.                 RAISERROR(20018, 16, -1)
  10141.                 RETURN(1)
  10142.             END
  10143.  
  10144.             SELECT @command = @command + @optional_command_line
  10145.  
  10146.             -- Get Distribution category name (assumes category_id = 10)
  10147.             select @category_name = name FROM msdb.dbo.syscategories where category_id = 10
  10148.  
  10149.             EXEC @retcode = dbo.sp_MSadd_repl_job
  10150.                     @name = @job_name,
  10151.                     @subsystem = 'Distribution',
  10152.                     @server = @@SERVERNAME,
  10153.                     @databasename = @distribution_db,
  10154.                     @enabled = 1,
  10155.                     @freqtype = @frequency_type,
  10156.                     @freqinterval = @frequency_interval,
  10157.                     @freqsubtype = @frequency_subday,
  10158.                     @freqsubinterval = @frequency_subday_interval,
  10159.                     @freqrelativeinterval = @frequency_relative_interval,
  10160.                     @freqrecurrencefactor = @frequency_recurrence_factor,
  10161.                     @activestartdate = @active_start_date,
  10162.                     @activeenddate = @active_end_date,
  10163.                     @activestarttimeofday = @active_start_time_of_day,
  10164.                     @activeendtimeofday = @active_end_time_of_day,
  10165.                     @command = @command,
  10166.                     @category_name = @category_name,
  10167.                     @retryattempts = 10,
  10168.                     @retrydelay = 1,
  10169.                     @job_id = @distribution_jobid OUTPUT
  10170.  
  10171.             IF @@ERROR <> 0 or @retcode <> 0
  10172.             BEGIN
  10173.                 IF @@TRANCOUNT = 1
  10174.                     ROLLBACK TRAN
  10175.                 ELSE
  10176.                     COMMIT TRAN   
  10177.                 RETURN(1)
  10178.             END
  10179.         end
  10180.         else
  10181.         begin
  10182.             select @distribution_jobid = job_id from msdb..sysjobs_view where 
  10183.                 name = @job_name collate database_default and
  10184.                 UPPER(originating_server) = UPPER(CONVERT(sysname, SERVERPROPERTY('ServerName')))
  10185.             if @distribution_jobid IS NULL
  10186.             begin
  10187.                 -- Message from msdb.dbo.sp_verify_job_identifiers
  10188.                 RAISERROR(14262, -1, -1, 'Job', @job_name)          
  10189.                 IF @@TRANCOUNT = 1
  10190.                     ROLLBACK TRAN
  10191.                 ELSE
  10192.                     COMMIT TRAN   
  10193.                 RETURN(1)
  10194.             end
  10195.         end
  10196.     END
  10197.  
  10198.     if @reserved <> 'no_change_to_properties' and (@subscription_type_id = 1) OR (@subscription_type_id = 2)
  10199.     BEGIN
  10200.         IF NOT EXISTS (select * from MSsubscription_properties 
  10201.             where UPPER(publisher) = UPPER(@publisher)
  10202.               and publisher_db =  @publisher_db
  10203.               and publication = @publication) 
  10204.         BEGIN
  10205.             -- Publication type:
  10206.             -- 0  transactional
  10207.             -- 1  snapshot
  10208.             -- 2  merge (not allowed)
  10209.  
  10210.             INSERT INTO MSsubscription_properties 
  10211.             (publisher, publisher_db, publication, publication_type, 
  10212.              publisher_login,publisher_password, publisher_security_mode, 
  10213.              distributor, distributor_login, distributor_password, 
  10214.              distributor_security_mode, ftp_address, ftp_port, ftp_login, 
  10215.              ftp_password, alt_snapshot_folder, working_directory, use_ftp,
  10216.              dts_package_name, dts_package_password, dts_package_location, 
  10217.              offload_agent, offload_server, dynamic_snapshot_location)
  10218.             values (@publisher, @publisher_db, @publication, @publication_type, NULL, NULL, 1, 
  10219.                 @distributor, @distributor_login, @distributor_enc_password, 
  10220.                 @distributor_security_mode, null, null, null,
  10221.                 null, @alt_snapshot_folder, @working_directory, @use_ftp_bit,
  10222.                 @dts_package_name, @dts_package_enc_password, 
  10223.                 @dts_package_location_id, @offload_agent_bit, @offloadserver, null)
  10224.  
  10225.             IF @@ERROR <> 0 
  10226.             BEGIN
  10227.                 IF @@TRANCOUNT = 1
  10228.                     ROLLBACK TRAN
  10229.                 ELSE
  10230.                     COMMIT TRAN           
  10231.                 RETURN(1)
  10232.             END
  10233.         END
  10234.         ELSE
  10235.         BEGIN
  10236.             update MSsubscription_properties set
  10237.                 distributor = @distributor,
  10238.                 distributor_login = @distributor_login,
  10239.                 distributor_password = @distributor_enc_password,
  10240.                 distributor_security_mode = @distributor_security_mode,
  10241.                 dts_package_name = @dts_package_name,
  10242.                 dts_package_password = @dts_package_enc_password,
  10243.                 dts_package_location = @dts_package_location_id
  10244.                 where UPPER(publisher) = UPPER(@publisher)
  10245.                     and publisher_db =  @publisher_db
  10246.                     and publication = @publication
  10247.         END
  10248.  
  10249.  
  10250.         -- For dependent subscriptions we need to fix up all the
  10251.         -- shared properties  
  10252.         IF @independent_agent_id = 0 
  10253.         BEGIN
  10254.  
  10255.             EXEC @retcode = sp_MSfixupsharedagentproperties
  10256.                    @publisher = @publisher,
  10257.                    @publisher_db = @publisher_db,
  10258.                    @publication = @publication,
  10259.                    @distributor = @distributor,
  10260.                    @distributor_security_mode = @distributor_security_mode,
  10261.                    @distributor_login = @distributor_login,
  10262.                    @distributor_password = @distributor_enc_password,
  10263.                    @ftp_address = @ftp_address,
  10264.                    @ftp_port = @ftp_port,
  10265.                    @ftp_login = @ftp_login,
  10266.                    @ftp_password = @ftp_password,
  10267.                    @alt_snapshot_folder = @alt_snapshot_folder,
  10268.                    @working_directory = @working_directory,
  10269.                    @use_ftp = @use_ftp_bit,
  10270.                    @offload_agent = @offload_agent_bit,
  10271.                    @offload_server = @offloadserver
  10272.                     
  10273.             IF @retcode <> 0 OR @@ERROR <> 0
  10274.             BEGIN
  10275.             IF @@TRANCOUNT = 1
  10276.                 ROLLBACK TRAN
  10277.             ELSE
  10278.                 COMMIT TRAN           
  10279.             RETURN(1)
  10280.             END
  10281.         END
  10282.  
  10283.         IF @@ERROR <> 0 
  10284.         BEGIN
  10285.             IF @@TRANCOUNT = 1
  10286.                 ROLLBACK TRAN
  10287.             ELSE
  10288.                 COMMIT TRAN           
  10289.             RETURN(1)
  10290.         END
  10291.     END
  10292.  
  10293.  
  10294.     /* If we do not have independent agents , i.e. independent_agent=0, but there is
  10295.     already a row for that publisher and that publisher database with a NOT null 
  10296.     distribution_agent_id, then set the @distribution_jobid to that id.  Note that if
  10297.     there are no rows returned, the value of the variable does not change, which is what we want.
  10298.     There should never be more than one row ever returned for this query - but will use TOP 1
  10299.     to insist that is the case.
  10300.     */
  10301.     
  10302.     IF @independent_agent_id = 0
  10303.     BEGIN
  10304.         SELECT DISTINCT @distribution_jobid=agent_id, @job_name = distribution_agent 
  10305.           FROM MSreplication_subscriptions
  10306.          WHERE UPPER(publisher) = UPPER(@publisher) 
  10307.            AND publisher_db =  @publisher_db
  10308.            AND agent_id IS NOT NULL AND independent_agent=0
  10309.     
  10310.     END
  10311.  
  10312.     UPDATE MSreplication_subscriptions 
  10313.        SET distribution_agent = @job_name,
  10314.            agent_id = @distribution_jobid
  10315.      WHERE UPPER(publisher) = UPPER(@publisher) 
  10316.        AND publisher_db =  @publisher_db 
  10317.        AND publication =  @publication 
  10318.        AND (subscription_type = 1 /* pull*/ OR subscription_type = 2) /*anonymous*/
  10319.  
  10320.     IF @@ERROR <> 0 
  10321.     BEGIN
  10322.         IF @@TRANCOUNT = 1
  10323.             ROLLBACK TRAN
  10324.         ELSE
  10325.             COMMIT TRAN           
  10326.         RETURN(1)
  10327.     END 
  10328.  
  10329.     /* Conditional support for MobileSync */
  10330.     if LOWER(@enabled_for_syncmgr collate SQL_Latin1_General_CP1_CS_AS) = 'true'
  10331.     BEGIN
  10332.         /* Call sp_MSregistersubscription so that the subscription can be synchronized via MobileSync etc. */
  10333.         declare @subscription_id uniqueidentifier
  10334.         declare @failover_mode_id int
  10335.         set @subscription_id = convert(uniqueidentifier, @distribution_jobid)
  10336.  
  10337.         if @update_mode_id in (3,5) 
  10338.             select @failover_mode_id = 1
  10339.         else if @update_mode_id in (2,4)
  10340.             select @failover_mode_id = 2
  10341.         else
  10342.             select @failover_mode_id = 0
  10343.             
  10344.         exec @retcode = dbo.sp_MSregistersubscription @replication_type = 1,
  10345.                                     @publisher = @publisher,
  10346.                                     @publisher_db = @publisher_db,
  10347.                                     @publication = @publication,
  10348.                                     @subscriber = @subscriber,
  10349.                                     @subscriber_db = @subscriber_db,
  10350.                                     @subscriber_security_mode = @subscriber_security_mode,
  10351.                                     @subscriber_login = @subscriber_login,
  10352.                                     @subscriber_password = @subscriber_password,
  10353.                                     @distributor = @distributor,
  10354.                                     @subscription_id = @subscription_id,
  10355.                                     @independent_agent = @independent_agent_id,
  10356.                                     @subscription_type = @subscription_type_id,
  10357.                                     @failover_mode = @failover_mode_id
  10358.         IF @@ERROR <> 0 or @retcode <> 0
  10359.         BEGIN
  10360.             IF @@TRANCOUNT = 1
  10361.                 ROLLBACK TRAN
  10362.             ELSE
  10363.                 COMMIT TRAN           
  10364.             RETURN(1)
  10365.         END
  10366.     END
  10367.  
  10368.     COMMIT TRAN
  10369.     RETURN(0)
  10370. GO
  10371.  
  10372.  
  10373.  
  10374.  
  10375.  
  10376.  
  10377. raiserror('Creating procedure sp_helpsubscription_properties
  10378. ', 0,1)
  10379. go
  10380. CREATE PROCEDURE sp_helpsubscription_properties
  10381.         @publisher sysname = '%', 
  10382.         @publisher_db sysname = '%', 
  10383.         @publication sysname = '%', 
  10384.         @publication_type int = NULL
  10385.     AS
  10386.  
  10387.     SET NOCOUNT ON
  10388.     DECLARE @retcode int
  10389.  
  10390.     /*
  10391.     ** Security Check
  10392.     */
  10393.  
  10394.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  10395.     IF @@ERROR <> 0 or @retcode <> 0
  10396.         RETURN(1)
  10397.  
  10398.     /*
  10399.     ** The logic is added here for the case where MSsubscription_properties table does not exist
  10400.     ** or relevant entry is not added because sp_addmergepullsubscription_agent or sp_addsubscription_agent
  10401.     ** is not called.
  10402.     */
  10403.     IF NOT EXISTS (select * from sysobjects where name = 'MSsubscription_properties' and type = 'U')
  10404.     begin
  10405.         return (0)
  10406.     end
  10407.  
  10408.     IF (@publisher IS NULL) OR (@publisher = '')
  10409.         select @publisher = '%'
  10410.     IF (@publisher_db IS NULL) OR (@publisher_db = '')
  10411.         select @publisher_db = '%'
  10412.     IF (@publication IS NULL) OR (@publication = '')
  10413.         select @publication = '%'
  10414.  
  10415.     IF @publication_type IS NOT NULL
  10416.     BEGIN
  10417.         SELECT publisher, publisher_db, publication, publication_type, publisher_login,
  10418.                publisher_password, publisher_security_mode, distributor, distributor_login,
  10419.                distributor_password, distributor_security_mode, 'ftp_address' = null, 'ftp_port' = 0,
  10420.                'ftp_login' = null, 'ftp_password' = null, alt_snapshot_folder, working_directory, use_ftp,
  10421.                dts_package_name, dts_package_password, dts_package_location, 
  10422.                offload_agent, offload_server, dynamic_snapshot_location 
  10423.           FROM MSsubscription_properties
  10424.          WHERE ((@publisher = N'%') OR (UPPER(publisher) = UPPER(@publisher)))
  10425.            AND ((@publisher_db = N'%') or ( publisher_db = @publisher_db))
  10426.            AND publication LIKE @publication
  10427.            AND publication_type = @publication_type
  10428.     END
  10429.     ELSE
  10430.     BEGIN
  10431.         SELECT publisher, publisher_db, publication, publication_type, publisher_login,
  10432.                publisher_password, publisher_security_mode, distributor, distributor_login,
  10433.                distributor_password, distributor_security_mode, 'ftp_address' = null, 'ftp_port' = 0,
  10434.                'ftp_login' = null, 'ftp_password' = null, alt_snapshot_folder, working_directory, use_ftp,
  10435.                dts_package_name, dts_package_password, dts_package_location,
  10436.                offload_agent, offload_server, dynamic_snapshot_location
  10437.           FROM MSsubscription_properties
  10438.          WHERE ((@publisher = N'%') OR (UPPER(publisher) = UPPER(@publisher)))
  10439.            AND ((@publisher_db = N'%') or ( publisher_db = @publisher_db))
  10440.            AND publication LIKE @publication
  10441.     END
  10442.  
  10443.     RETURN (0)
  10444. GO
  10445.  
  10446. EXEC dbo.sp_MS_marksystemobject sp_helpsubscription_properties
  10447. GO
  10448.  
  10449. raiserror('Creating procedure sp_change_subscription_properties', 0,1)
  10450. go
  10451. CREATE PROCEDURE sp_change_subscription_properties
  10452.         @publisher sysname, 
  10453.         @publisher_db sysname, 
  10454.         @publication sysname, 
  10455.         @property sysname,
  10456.         @value nvarchar(1000),
  10457.         @publication_type int = NULL
  10458.     AS
  10459.     SET NOCOUNT ON
  10460.  
  10461.     DECLARE @command nvarchar(2000)
  10462.     DECLARE @column_to_update nvarchar(64)
  10463.     DECLARE @value_string nvarchar(255)
  10464.     DECLARE @independent_agent bit
  10465.     DECLARE @retcode int
  10466.     DECLARE @subscription_type int
  10467.     DECLARE @intvalue int
  10468.     DECLARE @value_bit bit
  10469.     DECLARE @offload_agent bit
  10470.     DECLARE @offload_server sysname 
  10471.     DECLARE @dbname sysname
  10472.     DECLARE @local_publication sysname
  10473.     DECLARE @agentid binary(16)
  10474.     DECLARE @local_publisher sysname
  10475.     DECLARE @cursor_opened bit 
  10476.     DECLARE @cursor_allocated bit
  10477.     DECLARE @agenttype nvarchar(20)
  10478.     DECLARE @commandline nvarchar(3200)
  10479.  
  10480.     SELECT @cursor_opened = 0
  10481.     SELECT @cursor_allocated = 0
  10482.     SELECT @retcode = 0    
  10483.     /*
  10484.     ** Security Check
  10485.     */
  10486.  
  10487.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  10488.     IF @@ERROR <> 0 or @retcode <> 0
  10489.         RETURN(1)
  10490.  
  10491.     IF NOT EXISTS (select * from sysobjects where name = 'MSsubscription_properties' and type = 'U')
  10492.     begin
  10493.         raiserror(14027, 16, -1, 'The subscription properties table ''MSsubscription_properties''')
  10494.         return (1)
  10495.     end
  10496.     
  10497.     if (@publisher is null)
  10498.     begin
  10499.         raiserror(14043, 16, -1, '@publisher')
  10500.         return (1)
  10501.     end
  10502.  
  10503.     if(@publisher_db is null)
  10504.     begin
  10505.         raiserror(14043, 16, -1, '@publisher_db')
  10506.         return (1)
  10507.     end
  10508.     
  10509.     if (@publication is null) or (@publication = '')
  10510.     begin
  10511.         select @publication = '%'
  10512.     end
  10513.  
  10514.  
  10515.     -- Expand '%' into individual subscriptions using a cursor
  10516.     IF @publication = N'%'
  10517.     BEGIN
  10518.  
  10519.         BEGIN TRANSACTION subscription_properties_exp
  10520.         DECLARE hsubprop CURSOR LOCAL FAST_FORWARD FOR
  10521.             SELECT publication 
  10522.               FROM MSreplication_subscriptions
  10523.              WHERE UPPER(publisher) = UPPER(@publisher)
  10524.                AND publisher_db = @publisher_db
  10525.                -- NOTE:  publication like '%' is implicit
  10526.         IF @@ERROR <> 0
  10527.             GOTO ExpFailure
  10528.         SELECT @cursor_allocated = 1
  10529.     
  10530.         OPEN hsubprop
  10531.         IF @@ERROR <> 0
  10532.             GOTO ExpFailure    
  10533.         SELECT @cursor_opened = 1
  10534.  
  10535.         FETCH hsubprop INTO @local_publication
  10536.         WHILE (@@FETCH_STATUS <> 0)
  10537.         BEGIN
  10538.                             
  10539.             EXEC @retcode = sp_change_subscription_properties
  10540.                 @publisher = @publisher,
  10541.                 @publisher_db = @publisher_db,
  10542.                 @publication = @local_publication,
  10543.                 @property = @property,
  10544.                 @value = @value,
  10545.                 @publication_type = @publication_type
  10546.             IF @retcode <> 0 OR @@ERROR <> 0
  10547.                 GOTO ExpFailure
  10548.             FETCH hsubprop INTO @local_publication
  10549.         END
  10550.  
  10551.         CLOSE hsubprop
  10552.         DEALLOCATE hsubprop
  10553.         COMMIT TRANSACTION subscription_properties_exp
  10554.         IF @@ERROR <> 0
  10555.             GOTO ExpFailure
  10556.  
  10557.         RETURN (0)
  10558. ExpFailure:
  10559.  
  10560.         IF @cursor_opened = 1
  10561.             CLOSE hsubprop
  10562.         IF @cursor_allocated = 1
  10563.             DEALLOCATE hsubprop
  10564.         ROLLBACK TRANSACTION subscription_properties_exp        
  10565.         RETURN (1)
  10566.     END    
  10567.  
  10568.     -- Check for existence of the specified pull subscription
  10569.     SELECT @agentid = NULL
  10570.     SELECT @local_publisher = NULL
  10571.     SELECT @dbname = DB_NAME()
  10572.  
  10573.     IF @publication_type IN (0,1) OR @publication_type IS NULL
  10574.     BEGIN
  10575.         IF EXISTS (SELECT * FROM sysobjects WHERE id = object_id('MSreplication_subscriptions'))
  10576.         BEGIN
  10577.             SELECT @local_publisher = publisher, 
  10578.                    @agentid = agent_id
  10579.               FROM MSreplication_subscriptions
  10580.              WHERE UPPER(publisher) = UPPER(@publisher)
  10581.                AND publisher_db = @publisher_db
  10582.                AND publication = @publication 
  10583.         END
  10584.  
  10585.     END
  10586.  
  10587.     IF @publication_type = 2 OR (@publication_type IS NULL AND
  10588.         @local_publisher IS NULL)
  10589.     BEGIN
  10590.         IF EXISTS (SELECT * FROM sysobjects WHERE id = object_id('sysmergepublications'))
  10591.         BEGIN
  10592.  
  10593.             SELECT @local_publisher = mp.publisher,
  10594.                    @agentid = mr.merge_jobid
  10595.               FROM sysmergepublications mp
  10596.             INNER JOIN sysmergesubscriptions ms
  10597.                 ON mp.pubid = ms.pubid 
  10598.                AND UPPER(mp.publisher) = UPPER(@publisher) 
  10599.                AND mp.publisher_db = @publisher_db
  10600.                AND mp.name = @publication 
  10601.                AND ms.db_name = @dbname
  10602.                AND UPPER(ms.subscriber_server) = UPPER(@@SERVERNAME)
  10603.             INNER JOIN MSmerge_replinfo mr
  10604.                 ON ms.subid = mr.repid
  10605.         END
  10606.     END 
  10607.  
  10608.     IF @local_publisher IS NULL
  10609.     BEGIN
  10610.         RAISERROR(21226, 16, -1, @dbname)
  10611.         RETURN (1)
  10612.     END
  10613.  
  10614.     SELECT @offload_agent = NULL
  10615.     SELECT @offload_server = NULL
  10616.     SELECT @offload_agent = offload_agent, 
  10617.            @offload_server = offload_server,
  10618.            @publication_type = publication_type             
  10619.       FROM MSsubscription_properties 
  10620.      WHERE UPPER(publisher) = UPPER(@publisher)
  10621.        AND publisher_db = @publisher_db
  10622.        AND publication = @publication
  10623.     
  10624.     -- If the subscription does not have a corresponding entry in MSsubscription_properties, 
  10625.     -- the subscription is probably created by the ActiveX control. In this case there isn't much
  10626.     -- we can do about it so we just return 0.
  10627.     IF @offload_agent IS NULL
  10628.     BEGIN
  10629.         RETURN (0)
  10630.     END      
  10631.     
  10632.     IF (@property IS NULL)
  10633.     begin
  10634.         raiserror(14043, 16, -1, '@property')
  10635.         return (1)
  10636.     end
  10637.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'publisher_login')
  10638.         select @column_to_update = 'publisher_login'
  10639.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'publisher_password')
  10640.     begin
  10641.         select @column_to_update = 'publisher_password'
  10642.         EXEC @retcode = master.dbo.xp_repl_encrypt @value OUTPUT
  10643.         IF @@error <> 0 OR @retcode <> 0
  10644.             return 1
  10645.     end
  10646.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'publisher_security_mode')
  10647.         select @column_to_update = 'publisher_security_mode'
  10648.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'distributor')
  10649.         select @column_to_update = 'distributor'
  10650.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'distributor_login')
  10651.         select @column_to_update = 'distributor_login'
  10652.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'distributor_password')
  10653.     begin
  10654.         select @column_to_update = 'distributor_password'
  10655.         EXEC @retcode = master.dbo.xp_repl_encrypt @value OUTPUT
  10656.         IF @@error <> 0 OR @retcode <> 0
  10657.             return 1
  10658.     end
  10659.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'distributor_security_mode')
  10660.         select @column_to_update = 'distributor_security_mode'
  10661.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'ftp_address')
  10662.         select @column_to_update = 'ftp_address'
  10663.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'ftp_port')
  10664.         select @column_to_update = 'ftp_port'
  10665.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'ftp_login')
  10666.         select @column_to_update = 'ftp_login'
  10667.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'ftp_password')
  10668.         select @column_to_update = 'ftp_password'
  10669.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'alt_snapshot_folder')
  10670.     BEGIN
  10671.         select @column_to_update = 'alt_snapshot_folder'
  10672.     END
  10673.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'working_directory')
  10674.     BEGIN
  10675.         select @column_to_update = 'working_directory'
  10676.     END
  10677.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'use_ftp')
  10678.         select @column_to_update = 'use_ftp'
  10679.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'dts_package_name')
  10680.         select @column_to_update = 'dts_package_name'
  10681.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'dts_package_password')
  10682.     begin
  10683.         select @column_to_update = 'dts_package_password'
  10684.         EXEC @retcode = master.dbo.xp_repl_encrypt @value OUTPUT
  10685.         IF @@error <> 0 OR @retcode <> 0
  10686.             return 1
  10687.     end
  10688.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'dts_package_location')
  10689.         select @column_to_update = 'dts_package_location'
  10690.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'offload_agent')
  10691.     BEGIN
  10692.         select @column_to_update = 'offload_agent'
  10693.     END
  10694.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'offload_server')
  10695.     BEGIN
  10696.         select @column_to_update = 'offload_server'
  10697.         exec @retcode = sp_MSreplcheckoffloadserver @value
  10698.         if @retcode <> 0 or @@error <> 0
  10699.                 return(1)
  10700.     END
  10701.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = N'dynamic_snapshot_location') and @publication_type = 2
  10702.     BEGIN
  10703.         select @column_to_update = N'dynamic_snapshot_location'
  10704.     END
  10705.     ELSE
  10706.     BEGIN
  10707.         raiserror (3217, 16, -1, '@property')
  10708.         return(1)
  10709.     END
  10710.  
  10711.     IF @column_to_update in ('use_ftp', 'offload_agent')
  10712.     BEGIN
  10713.         IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) = N'true'
  10714.         BEGIN
  10715.             SELECT @value_bit = 1
  10716.         END
  10717.         ELSE IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) = N'false'
  10718.         BEGIN
  10719.             SELECT @value_bit = 0
  10720.         END
  10721.         ELSE
  10722.         BEGIN 
  10723.             RAISERROR(14137, 16, -1)
  10724.         END
  10725.     END
  10726.  
  10727.     IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'distributor_security_mode') OR (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'publisher_security_mode') 
  10728.     BEGIN
  10729.         IF NOT ( @value = 0 or @value = 1 or (@value = 2 and lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'publisher_security_mode' )) 
  10730.         BEGIN
  10731.             raiserror(3217, 16, -1, '@value')
  10732.             return(1)
  10733.         END
  10734.         select @value_string = convert(nvarchar(1), @value)
  10735.     END
  10736.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'dts_package_location')
  10737.     BEGIN
  10738.         IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) = N'distributor' 
  10739.             select @value_string = '0'
  10740.         ELSE IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) = N'subscriber' 
  10741.             select @value_string = '1'
  10742.         ELSE 
  10743.         begin
  10744.             raiserror(20587, 16, -1, 'dts_package_location', 'sp_change_subscription_properties')
  10745.             return(1)
  10746.         end
  10747.  
  10748.     END
  10749.     ELSE
  10750.     BEGIN
  10751.         IF @value IS NULL
  10752.         BEGIN
  10753.             select @value_string = 'null'
  10754.         END
  10755.         ELSE
  10756.         BEGIN
  10757.             select @value_string = 'N' + quotename(rtrim(@value),'''')
  10758.         END
  10759.     END    
  10760.  
  10761.     -- Ignore ftp_address, ftp_port, ftp_login, ftp_password on post 7.0 servers
  10762.     IF (@column_to_update IN (N'ftp_address', N'ftp_port', N'ftp_login', N'ftp_password'))
  10763.     BEGIN
  10764.         RETURN (0)
  10765.     END
  10766.  
  10767.     -- If the 'offload_agent' property is 1, 'offload_server' property must not be
  10768.     -- null or empty. Make sure that this is the case
  10769.     IF (@column_to_update = N'offload_agent' AND 
  10770.         @value_bit = 1 AND 
  10771.         (@offload_server IS NULL OR @offload_server = N''))
  10772.     BEGIN
  10773.         RAISERROR(21215, 16, -1)
  10774.         RETURN(1)
  10775.     END
  10776.  
  10777.     -- If we are enabling agent offload for this pull subscription, 
  10778.     -- we should make sure that the offload server is different from
  10779.     -- the Subscriber's server name
  10780.     IF (@column_to_update = N'offload_agent' AND
  10781.         @value_bit = 1 AND UPPER(@offload_server) = UPPER(@@SERVERNAME)) OR
  10782.        (@column_to_update = N'offload_server' AND
  10783.         @offload_agent = 1 AND 
  10784.         UPPER(@value) = UPPER(@@SERVERNAME))
  10785.     BEGIN
  10786.         RAISERROR(21227, 16, -1)
  10787.         RETURN (1)
  10788.     END
  10789.     
  10790. BEGIN TRANSACTION subscription_properties    
  10791.     IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'use_ftp')
  10792.     begin
  10793.         update MSsubscription_properties set use_ftp = @value_bit where 
  10794.             UPPER(publisher) = UPPER(@publisher) and 
  10795.             publisher_db = @publisher_db and
  10796.             publication = @publication 
  10797.         IF @@error <> 0 OR @retcode <> 0
  10798.             GOTO Failure
  10799.     end
  10800.     else if (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'offload_agent')
  10801.     begin
  10802.         update MSsubscription_properties set offload_agent = @value_bit where
  10803.             UPPER(publisher) = UPPER(@publisher) and
  10804.             publisher_db = @publisher_db and
  10805.             publication = @publication
  10806.         IF @@error <> 0 OR @retcode <> 0
  10807.             GOTO Failure
  10808.  
  10809.         -- Call helper procedure to add or remove the '-Offload' parameter 
  10810.         -- from the agent's command line in msdb. By now, we should 
  10811.         -- have the publication type and the agent jodid.
  10812.  
  10813.         -- Don't do anything if the offload_agent property hasn't been changed
  10814.         IF @offload_agent <> @value_bit
  10815.         BEGIN
  10816.             IF @publication_type IN (0,1)    
  10817.             BEGIN
  10818.                 SELECT @agenttype = N'distribution'
  10819.             END
  10820.             ELSE
  10821.             BEGIN
  10822.                 SELECT @agenttype = N'merge'
  10823.             END    
  10824.  
  10825.             -- Add or remove the Offload parameter based on the new value
  10826.             -- of the offload_agent property 
  10827.             IF @value_bit = 0
  10828.             BEGIN
  10829.                 EXEC @retcode = sp_MSremoveoffloadparameter
  10830.                         @job_id = @agentid,
  10831.                         @agenttype = @agenttype
  10832.  
  10833.                 IF @@ERROR <> 0 OR @retcode <> 0
  10834.                     GOTO Failure 
  10835.             END
  10836.             ELSE
  10837.             BEGIN
  10838.                 EXEC @retcode = sp_MSaddoffloadparameter 
  10839.                         @job_id = @agentid,
  10840.                         @offloadserver = @offload_server,
  10841.                         @agenttype = @agenttype
  10842.  
  10843.                 IF @@ERROR <> 0 OR @retcode <> 0
  10844.                     GOTO Failure 
  10845.             END
  10846.         END
  10847.     end
  10848.     else if lower(@property collate SQL_Latin1_General_CP1_CS_AS) = N'dynamic_snapshot_location'
  10849.     begin
  10850.         select @value = rtrim(ltrim(@value))
  10851.  
  10852.         update MSsubscription_properties 
  10853.            set dynamic_snapshot_location = @value
  10854.          where upper(publisher) = upper(@publisher) 
  10855.            and publisher_db = @publisher_db 
  10856.            and publication = @publication
  10857.         if @@error <> 0 or @retcode <> 0
  10858.             goto Failure
  10859.  
  10860.         -- Call helper functions to add/update or remove the -DynamicSnapshotLocationParameter
  10861.         if @value is null or @value = N''
  10862.         begin
  10863.             update msdb.dbo.sysjobsteps 
  10864.                set command = fn_removeparameterwithargument(command, N'DynamicSnapshotLocation') collate database_default
  10865.              where job_id = @agentid
  10866.                and lower(subsystem collate SQL_Latin1_General_CP1_CS_AS) = N'merge'
  10867.         end
  10868.         else
  10869.         begin
  10870.  
  10871.             select @commandline = command 
  10872.               from msdb.dbo.sysjobsteps
  10873.              where job_id = @agentid
  10874.                and lower(subsystem collate SQL_Latin1_General_CP1_CS_AS) = N'merge'
  10875.  
  10876.             select @commandline = fn_updateparameterwithargument(@commandline, N'DynamicSnapshotLocation', fn_replquotename(@value)) collate database_default
  10877.  
  10878.             -- Need to remove existing alternate snapshot folder parameters
  10879.             -- and file transfer type parameters
  10880.  
  10881.             select @commandline = fn_removeparameterwithargument(@commandline, N'FileTransferType') collate database_default
  10882.             
  10883.             select @commandline = fn_removeparameterwithargument(@commandline, N'AltSnapshotFolder') collate database_default
  10884.  
  10885.             update msdb.dbo.sysjobsteps
  10886.                set command = @commandline
  10887.              where job_id = @agentid
  10888.                and lower(subsystem collate SQL_Latin1_General_CP1_CS_AS) = N'merge' 
  10889.  
  10890.         end
  10891.     end
  10892.     else    
  10893.     begin
  10894.         -- Password is encrypted. Must prefix every string with N' 
  10895.         -- otherwise, the chars will be convert to '???'
  10896.         select @command = N'update MSsubscription_properties set ' + @column_to_update + '= ' + @value_string
  10897.                 + ' where UPPER(publisher) = UPPER(' + quotename(@publisher,'''') 
  10898.                 + ') and publisher_db = ' + quotename(@publisher_db, '''')
  10899.                 + ' and publication = ' + quotename(@publication,'''')
  10900.         EXEC (@command)
  10901.         IF @@error <> 0 OR @retcode <> 0
  10902.             GOTO Failure
  10903.     end
  10904.  
  10905.  
  10906.     -- If the offload_server property is chnaged, we have to modify the agent's
  10907.     -- command line if the agent has already been enabled for remote activation         
  10908.     IF @column_to_update = N'offload_server' AND @offload_agent = 1
  10909.     BEGIN
  10910.         IF @publication_type IN (0,1)
  10911.         BEGIN
  10912.             SELECT @agenttype = N'distribution'
  10913.         END
  10914.         ELSE
  10915.         BEGIN
  10916.             SELECT @agenttype = N'merge'
  10917.         END
  10918.  
  10919.         EXEC @retcode = sp_MSaddoffloadparameter
  10920.             @job_id = @agentid,
  10921.             @offloadserver = @value,
  10922.             @agenttype = @agenttype        
  10923.         IF @retcode <> 0 OR @@ERROR <> 0
  10924.             GOTO Failure
  10925.     END
  10926.  
  10927.     IF (@publication_type = 0 or @publication_type = 1) AND @publication <> N'%' AND
  10928.         @column_to_update IN ('distributor',
  10929.                               'distributor_login',
  10930.                               'distributor_password',
  10931.                               'distributor_security_mode',
  10932.                               'ftp_address',
  10933.                               'ftp_port',
  10934.                               'ftp_login',
  10935.                               'ftp_password',
  10936.                               'alt_snapshot_folder',
  10937.                               'working_dir',
  10938.                               'use_ftp',
  10939.                               'offload_agent',
  10940.                               'offload_server')
  10941.     BEGIN
  10942.         SELECT @subscription_type = subscription_type
  10943.           FROM MSreplication_subscriptions
  10944.          WHERE UPPER(publisher) = UPPER(@publisher)
  10945.            AND publisher_db = @publisher_db
  10946.            AND publication = @publication
  10947.         IF @@error <> 0 OR @retcode <> 0
  10948.             GOTO Failure
  10949.  
  10950.         -- Update the property for all shared subscriptions
  10951.         IF @column_to_update IN ('distributor_security_mode', 
  10952.                                  'ftp_port')
  10953.         BEGIN
  10954.             SELECT @intvalue = CONVERT(int, @value)
  10955.             EXEC @retcode = sp_MSupdatesharedagentproperties 
  10956.                     @publisher = @publisher,
  10957.                     @publisher_db = @publisher_db,
  10958.                     @publication = @publication,
  10959.                     @property = @column_to_update,
  10960.                     @intvalue = @intvalue,
  10961.                     @subscription_type = @subscription_type
  10962.         END
  10963.         ELSE IF @column_to_update IN ('use_ftp', 'offload_agent')
  10964.         BEGIN
  10965.             EXEC @retcode = sp_MSupdatesharedagentproperties 
  10966.                     @publisher = @publisher,
  10967.                     @publisher_db = @publisher_db,
  10968.                     @publication = @publication,
  10969.                     @property = @column_to_update,
  10970.                     @intvalue = @value_bit,
  10971.                     @subscription_type = @subscription_type
  10972.         END
  10973.         ELSE 
  10974.         BEGIN
  10975.             EXEC @retcode = sp_MSupdatesharedagentproperties 
  10976.                     @publisher = @publisher,
  10977.                     @publisher_db = @publisher_db,
  10978.                     @publication = @publication,
  10979.                     @property = @column_to_update,
  10980.                     @strvalue = @value,
  10981.                     @subscription_type = @subscription_type
  10982.         END  
  10983.     
  10984.         IF @@error <> 0 OR @retcode <> 0
  10985.             GOTO Failure
  10986.     END
  10987.  
  10988.     -- Ftp and alternate snapshot folder are mutually 
  10989.     -- exclusive options but instead of raising an error
  10990.     -- when both of them are non-null, nullify the other 
  10991.     -- property when either one of them is set to non-null
  10992.     -- value since properties can only be set one at a time
  10993.  
  10994.     -- 'dynamic_snapshot_location' should also be added to the
  10995.     -- list of mutually exclusive properties
  10996.  
  10997.  
  10998.     IF (@column_to_update = 'ftp_address') AND (@value <> N''
  10999.        AND @value IS NOT NULL)
  11000.     BEGIN
  11001.         EXEC @retcode = sp_change_subscription_properties 
  11002.                 @publisher = @publisher,
  11003.                 @publisher_db = @publisher_db,
  11004.                 @publication = @publication,
  11005.                 @property = 'alt_snapshot_folder',
  11006.                 @value = NULL
  11007.  
  11008.         IF @@error <> 0 OR @retcode <> 0
  11009.             GOTO Failure
  11010.     END
  11011.  
  11012.     IF (@column_to_update = 'use_ftp') AND (@value_bit = 1)
  11013.     BEGIN
  11014.         EXEC @retcode = sp_change_subscription_properties 
  11015.                 @publisher = @publisher,
  11016.                 @publisher_db = @publisher_db,
  11017.                 @publication = @publication,
  11018.                 @property = 'alt_snapshot_folder',
  11019.                 @value = NULL
  11020.  
  11021.         IF @@error <> 0 OR @retcode <> 0
  11022.             GOTO Failure
  11023.  
  11024.         IF @publication_type = 2
  11025.         BEGIN
  11026.             EXEC @retcode = sp_change_subscription_properties
  11027.                     @publisher = @publisher,
  11028.                     @publisher_db = @publisher_db,
  11029.                     @publication = @publication,
  11030.                     @property = 'dynamic_snapshot_location',
  11031.                     @value = NULL
  11032.             IF @@error <> 0 OR @retcode <> 0
  11033.                 GOTO Failure
  11034.         END
  11035.     END
  11036.  
  11037.     IF (@column_to_update = 'alt_snapshot_folder') AND (@value <> N''
  11038.        AND @value IS NOT NULL)
  11039.     BEGIN
  11040.         EXEC @retcode = sp_change_subscription_properties 
  11041.                 @publisher = @publisher,
  11042.                 @publisher_db = @publisher_db,
  11043.                 @publication = @publication,
  11044.                 @property = 'ftp_address',
  11045.                 @value = NULL
  11046.  
  11047.         IF @@error <> 0 OR @retcode <> 0
  11048.             GOTO Failure
  11049.  
  11050.         EXEC @retcode = sp_change_subscription_properties 
  11051.                 @publisher = @publisher,
  11052.                 @publisher_db = @publisher_db,
  11053.                 @publication = @publication,
  11054.                 @property = 'use_ftp',
  11055.                 @value = 'false'
  11056.  
  11057.         IF @@error <> 0 OR @retcode <> 0
  11058.             GOTO Failure
  11059.  
  11060.         IF @publication_type = 2
  11061.         BEGIN
  11062.             EXEC @retcode = sp_change_subscription_properties
  11063.                     @publisher = @publisher,
  11064.                     @publisher_db = @publisher_db,
  11065.                     @publication = @publication,
  11066.                     @property = 'dynamic_snapshot_location',
  11067.                     @value = NULL
  11068.             IF @@error <> 0 OR @retcode <> 0
  11069.                 GOTO Failure
  11070.         END
  11071.     END
  11072.  
  11073.  
  11074.     IF (@column_to_update = 'dynamic_snapshot_location') AND (@value <> N''
  11075.         AND @value IS NOT NULL)
  11076.     BEGIN
  11077.  
  11078.         EXEC @retcode = sp_change_subscription_properties
  11079.                 @publisher = @publisher,
  11080.                 @publisher_db = @publisher_db,
  11081.                 @publication = @publication,
  11082.                 @property = 'ftp_address',
  11083.                 @value = NULL
  11084.             
  11085.         IF @@error <> 0 OR @retcode <> 0
  11086.             GOTO Failure
  11087.  
  11088.         EXEC @retcode = sp_change_subscription_properties
  11089.                 @publisher = @publisher,
  11090.                 @publisher_db = @publisher_db,
  11091.                 @publication = @publication,
  11092.                 @property = 'use_ftp',
  11093.                 @value = 'false'
  11094.             
  11095.         IF @@error <> 0 OR @retcode <> 0
  11096.             GOTO Failure
  11097.  
  11098.         EXEC @retcode = sp_change_subscription_properties
  11099.                 @publisher = @publisher,
  11100.                 @publisher_db = @publisher_db,
  11101.                 @publication = @publication,
  11102.                 @property = 'alt_snapshot_folder',
  11103.                 @value = NULL
  11104.             
  11105.         IF @@error <> 0 OR @retcode <> 0
  11106.             GOTO Failure
  11107.  
  11108.     END
  11109.  
  11110.  
  11111.     -- Turn off the offload agent bit if the 
  11112.     -- the new value of offload server happens to be null
  11113.     -- or empty
  11114.     IF (@column_to_update = 'offload_server' AND 
  11115.         (@value IS NULL OR @value = N'') AND
  11116.         @offload_agent = 1)
  11117.     BEGIN
  11118.         EXEC @retcode = sp_change_subscription_properties
  11119.                 @publisher = @publisher,
  11120.                 @publisher_db = @publisher_db,
  11121.                 @publication = @publication,
  11122.                 @property = 'offload_agent',
  11123.                 @value = 'false'
  11124.         IF @@error <> 0 OR @retcode <> 0
  11125.             GOTO Failure
  11126.     END
  11127.  
  11128.     IF @@error <> 0 OR @retcode <> 0
  11129.         GOTO Failure
  11130.  
  11131.     COMMIT TRANSACTION subscription_properties
  11132.     RETURN (0)
  11133.             
  11134. Failure:        
  11135.     ROLLBACK TRANSACTION subscription_properties
  11136.     RETURN (1)
  11137. GO
  11138. EXEC dbo.sp_MS_marksystemobject sp_change_subscription_properties
  11139. GO
  11140. grant execute on dbo.sp_change_subscription_properties to public
  11141.  
  11142. raiserror('Creating procedure sp_MSget_pullsubsagent_owner', 0,1)
  11143. go
  11144.  
  11145. CREATE PROCEDURE sp_MSget_pullsubsagent_owner (
  11146.     @publisher    sysname,
  11147.     @publisher_db sysname,
  11148.     @publication  sysname,   /* publication name */
  11149.     @owner_sid    varbinary(85) OUTPUT 
  11150.     ) AS
  11151.  
  11152.     declare @job_id uniqueidentifier
  11153.     set nocount on
  11154.  
  11155.     select @owner_sid = null
  11156.         
  11157.  
  11158.     if exists (select * from sysobjects 
  11159.                where type = 'U' and 
  11160.                      name = 'MSreplication_subscriptions')
  11161.     begin 
  11162.         -- Get the job_id corresponding to the publication
  11163.         select @job_id = agent_id
  11164.         from MSreplication_subscriptions
  11165.         where upper(@publisher) = upper(publisher) and
  11166.             @publisher_db = publisher_db and
  11167.             @publication = publication 
  11168.  
  11169.         -- Using the job_id in MSsubscription properties to get the owner_sid 
  11170.         -- in msdb..sysjobs    
  11171.         select @owner_sid = owner_sid
  11172.         from  msdb..sysjobs
  11173.         where @job_id = job_id
  11174.     end            
  11175. go 
  11176.  
  11177. exec dbo.sp_MS_marksystemobject 'sp_MSget_pullsubsagent_owner'
  11178.  
  11179. raiserror('Creating procedure sp_droppullsubscription', 0,1)
  11180. go
  11181.  
  11182. CREATE PROCEDURE sp_droppullsubscription (
  11183.     @publisher sysname,
  11184.     @publisher_db sysname,
  11185.     @publication sysname,   /* publication name */
  11186.     @reserved bit = 0
  11187.     ) AS
  11188.  
  11189.     SET NOCOUNT ON
  11190.  
  11191.     /*
  11192.     ** Declarations.
  11193.     */
  11194.  
  11195.  
  11196.     DECLARE @name nvarchar(255)
  11197.     DECLARE @retcode int
  11198.     DECLARE @agent_id binary(16)
  11199.     DECLARE @publisher_ex sysname          /* Expression used in the cursor */
  11200.     DECLARE @publisher_db_ex sysname     /* Expression used in the cursor */
  11201.     DECLARE @publication_ex sysname      /* Expression used in the cursor */
  11202.     DECLARE @expanded bit
  11203.     DECLARE @subscription_type_id int
  11204.     DECLARE @count_sub int
  11205.     DECLARE @drop_null_pub bit
  11206.     DECLARE @drop_push_bit bit
  11207.     DECLARE @push int
  11208.     DECLARE @implicit_transaction int
  11209.     DECLARE @close_cursor_at_commit int
  11210.     DECLARE @owner_sid varbinary(85)
  11211.     DECLARE @owner_name sysname
  11212.     DECLARE @qualified_publication_name nvarchar(512)
  11213.     
  11214.     /* 
  11215.     ** Initialization
  11216.     */
  11217.     SELECT @expanded = 0
  11218.     SELECT @drop_null_pub = 0
  11219.     SELECT @push = 0
  11220.  
  11221.     /*
  11222.     ** Get the original set value off IMPLICIT_TRANSACTIONS and CURSOR_CLOSE_ON_COMMIT
  11223.     **      before set these two to off
  11224.     */
  11225.     select @implicit_transaction = 0
  11226.     select @close_cursor_at_commit = 0
  11227.     IF (@reserved = 0)
  11228.     BEGIN
  11229.         SELECT @implicit_transaction = @@options & 2
  11230.         SELECT @close_cursor_at_commit = @@options & 4
  11231.         SET IMPLICIT_TRANSACTIONS OFF
  11232.         SET CURSOR_CLOSE_ON_COMMIT OFF
  11233.     END
  11234.  
  11235.     /*
  11236.     ** Security Check
  11237.     */
  11238.  
  11239.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  11240.     IF @@ERROR <> 0 or @retcode <> 0
  11241.         RETURN(1)
  11242.  
  11243.     SELECT @drop_push_bit = 0   
  11244.     
  11245.     /*
  11246.     ** Check parameter and set expressions used by cursor
  11247.     */
  11248.     
  11249.     /* Publisher */
  11250.     IF @publisher IS NULL
  11251.     BEGIN
  11252.         RAISERROR (14043, 16, -1, '@publisher')
  11253.         RETURN (1)
  11254.     END
  11255.  
  11256.     IF @publisher = 'all'
  11257.     BEGIN
  11258.         SELECT @publisher_ex = '%'
  11259.         SELECT @expanded = 1
  11260.     END
  11261.     ELSE
  11262.     BEGIN
  11263.         EXECUTE @retcode = dbo.sp_validname @publisher
  11264.         IF @retcode <> 0
  11265.         RETURN (1)
  11266.         SELECT @publisher_ex = @publisher
  11267.     END
  11268.  
  11269.  
  11270.     /* Publisher_db */
  11271.     IF @publisher_db IS NULL
  11272.     BEGIN
  11273.             RAISERROR (14043, 16, -1, '@publisher_db')
  11274.             RETURN (1)
  11275.     END
  11276.  
  11277.     IF @publisher_db = 'all'
  11278.     BEGIN
  11279.         SELECT @publisher_db_ex = '%'
  11280.         select @expanded = 1
  11281.     END
  11282.     ELSE
  11283.     BEGIN
  11284.         /*
  11285.         EXECUTE @retcode = dbo.sp_validname @publisher_db
  11286.         IF @retcode <> 0
  11287.         RETURN (1)
  11288.         */
  11289.         SELECT @publisher_db_ex = @publisher_db
  11290.     END
  11291.  
  11292.     /* 
  11293.     ** Publication
  11294.     ** '' is not a valid name but it may be in the publication name in the table. 
  11295.     */
  11296.     IF @publication IS NULL OR @publication = ''
  11297.     BEGIN
  11298.         SELECT @drop_null_pub = 1
  11299.     END
  11300.     ELSE IF @publication = 'all'
  11301.     BEGIN
  11302.         SELECT @publication_ex = '%'
  11303.         SELECT @expanded = 1
  11304.         SELECT @drop_null_pub = 1
  11305.     END
  11306.     ELSE
  11307.     BEGIN
  11308.         EXECUTE @retcode = dbo.sp_validname @publication
  11309.         IF @retcode <> 0
  11310.         RETURN (1)
  11311.         SELECT @publication_ex = @publication
  11312.     END
  11313.  
  11314.     /*
  11315.     ** Check to see if the  subscription table exists
  11316.     */
  11317.     IF NOT EXISTS (SELECT * FROM sysobjects 
  11318.                 WHERE type = 'U' AND
  11319.                       name = 'MSreplication_subscriptions')
  11320.     BEGIN
  11321.         IF @expanded = 0
  11322.         BEGIN
  11323.             RAISERROR(14135, 11, -1,  @publisher, 
  11324.                 @publisher_db, @publication)
  11325.             RETURN(1)
  11326.         END
  11327.         ELSE
  11328.             RETURN(0)
  11329.     END
  11330.  
  11331.     IF @expanded = 0 
  11332.     BEGIN 
  11333.         /*
  11334.         **
  11335.         ** Check to see if the subscription entry exists
  11336.         */
  11337.         IF  NOT EXISTS (SELECT * FROM  MSreplication_subscriptions 
  11338.                     WHERE UPPER(publisher) = UPPER(@publisher) AND
  11339.                       publisher_db = @publisher_db AND
  11340.                       publication = @publication)     
  11341.         BEGIN
  11342.             RAISERROR(14135, 11, -1, @publisher, @publisher_db, @publication)
  11343.             RETURN(1)
  11344.         END
  11345.  
  11346.         /* 
  11347.         ** Make sure the subscription is not push type if @drop_push_bit = 0
  11348.         */
  11349.         IF @drop_push_bit = 0
  11350.         BEGIN
  11351.             IF EXISTS (SELECT * FROM MSreplication_subscriptions 
  11352.                 WHERE UPPER(publisher) = UPPER(@publisher) AND
  11353.                   publisher_db = @publisher_db AND
  11354.                   publication = @publication AND
  11355.                   subscription_type = @push AND
  11356.                   @drop_push_bit = 0)
  11357.             BEGIN
  11358.                 RAISERROR(20017, 16, -1)
  11359.                 RETURN(1)
  11360.             END
  11361.         END
  11362.  
  11363.     END
  11364.     ELSE
  11365.     /* 
  11366.     ** Open a cursor and call recursively if
  11367.     ** parameters are expanded.
  11368.     */
  11369.     BEGIN
  11370.  
  11371.         /*      
  11372.         **  Note: Any expression check on null value is false
  11373.         ** @subscription_type_id is NULL <==> push
  11374.         ** @subscription_type_id is NOT NULL <==> non push
  11375.         */
  11376.         -- Have to use static cursor option because 
  11377.         DECLARE hCdroppullsubscription CURSOR STATIC LOCAL FORWARD_ONLY FOR
  11378.             SELECT DISTINCT publisher, publisher_db, publication    
  11379.                 FROM MSreplication_subscriptions
  11380.                 WHERE ((@publisher_ex = N'%') OR (UPPER(publisher) = UPPER(@publisher_ex))) AND
  11381.                                           ((@publisher_db_ex = N'%') OR ( publisher_db = @publisher_db_ex)) AND
  11382.                       (publication LIKE @publication_ex OR
  11383.                       (@drop_null_pub = 1 AND
  11384.                       publication IS NULL)) AND
  11385.                       ((@drop_push_bit =0 AND
  11386.                       subscription_type <> @push) OR
  11387.                       @drop_push_bit = 1)
  11388.         FOR READ ONLY
  11389.         OPEN hCdroppullsubscription
  11390.  
  11391.         FETCH hCdroppullsubscription INTO @publisher, 
  11392.             @publisher_db, @publication
  11393.         WHILE (@@fetch_status <> -1)
  11394.         BEGIN
  11395.             EXECUTE @retcode  = dbo.sp_droppullsubscription @publisher = @publisher, 
  11396.                 @publisher_db = @publisher_db, @publication = @publication, 
  11397.                 @reserved = 1
  11398.  
  11399.             FETCH hCdroppullsubscription INTO @publisher, 
  11400.                 @publisher_db, @publication
  11401.         END
  11402.  
  11403.         CLOSE hCdroppullsubscription
  11404.         DEALLOCATE hCdroppullsubscription
  11405.         RETURN (0)
  11406.     END
  11407.     
  11408.     /*
  11409.     ** Only members of the sysadmin group and the creator of the distribution
  11410.     ** agent can drop a pull subscription successfully. This behavior matches 
  11411.     ** the behavior of the sysjobs_view. DBO of the subscriber database, 
  11412.     ** sysadmins (owner is undefined) can drop a subscription if the owner_sid 
  11413.     ** is null.
  11414.     */
  11415.  
  11416.     EXEC sp_MSget_pullsubsagent_owner @publisher = @publisher,
  11417.                                       @publisher_db = @publisher_db,
  11418.                                       @publication = @publication,
  11419.                                       @owner_sid = @owner_sid OUTPUT
  11420.  
  11421.     IF (@owner_sid is not null AND
  11422.         (SUSER_SID() <> @owner_sid) AND
  11423.         (ISNULL(IS_SRVROLEMEMBER('sysadmin'),0) = 0))
  11424.     BEGIN
  11425.         SELECT @owner_name = SUSER_SNAME(@owner_sid)
  11426.         SELECT @qualified_publication_name = @publisher + N':' + 
  11427.                                              @publisher_db + N':' +
  11428.                                              @publication
  11429.         RAISERROR(21121,16,-1,@owner_name, @qualified_publication_name) 
  11430.         RETURN (1)
  11431.     END
  11432.  
  11433.     /* 
  11434.     ** Get the agent name, it may be dropped later.
  11435.     */
  11436.     SELECT @agent_id = agent_id FROM MSreplication_subscriptions
  11437.                     WHERE UPPER(publisher) = UPPER(@publisher) AND
  11438.                           publisher_db  = @publisher_db AND
  11439.                           publication = @publication 
  11440.  
  11441.     -- If the agent is used by other subscription, don't drop it.
  11442.     if (select count(*) from MSreplication_subscriptions where
  11443.         agent_id = @agent_id) > 1
  11444.         select @agent_id = NULL
  11445.  
  11446.     begin tran
  11447.     save TRAN droppullsubscription
  11448.  
  11449.     /*
  11450.     ** Drop the subscription entry and the distribution agent if it exists 
  11451.     */
  11452.  
  11453.  
  11454.     /* 
  11455.     ** If the distribution agent is not used anymore,
  11456.     ** drop the agent if it exists
  11457.     */
  11458.  
  11459.     IF @agent_id IS NOT NULL
  11460.     BEGIN
  11461.         IF (EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @agent_id))
  11462.         BEGIN
  11463.             -- Checks if the job name matches one that is generated
  11464.             -- by replication
  11465.             EXEC @retcode = dbo.sp_MSispulldistributionjobnamegenerated
  11466.                                @publisher = @publisher,
  11467.                                @publisher_db = @publisher_db,
  11468.                                @publication = @publication,
  11469.                                @job_id = @agent_id
  11470.             IF @@ERROR <> 0
  11471.                 GOTO UNDO
  11472.  
  11473.             -- Only drop jobs if the name was generated
  11474.             IF @retcode = 0
  11475.             BEGIN
  11476.                 EXEC @retcode = msdb.dbo.sp_delete_job @job_id = @agent_id
  11477.                 IF @@ERROR <> 0 or @retcode <> 0
  11478.                     GOTO UNDO
  11479.  
  11480.                 -- Delete MSreplication_subsciptions table after dropping 
  11481.                 -- the distribution agent and delay one second
  11482.                 -- to avoid deadlock with it.
  11483.                 WAITFOR DELAY '00:00:01'
  11484.             END
  11485.         END
  11486.  
  11487.     END
  11488.  
  11489.     /* Call sp_MSunregistersubscription so that the reg entries get deleted */
  11490.     declare @subscriber_db sysname
  11491.     set @subscriber_db = DB_NAME()
  11492.     exec @retcode = dbo.sp_MSunregistersubscription @publisher = @publisher,
  11493.                                 @publisher_db = @publisher_db,
  11494.                                 @publication = @publication,
  11495.                                 @subscriber = @@SERVERNAME,
  11496.                                 @subscriber_db = @subscriber_db
  11497.  
  11498.     IF @retcode<>0 or @@ERROR<>0
  11499.         GOTO UNDO
  11500.     /*
  11501.     -- Delete MSreplication_subsciptions table after dropping the distribution agent\
  11502.     -- To avoid deadlock with it.
  11503.     --DELETE MSreplication_subscriptions WHERE UPPER(publisher) = UPPER(@publisher) AND
  11504.         --publisher_db  = @publisher_db AND
  11505.         --publication = @publication 
  11506.     
  11507.     --IF @@ERROR <> 0 
  11508.     --  GOTO UNDO
  11509.  
  11510.     */
  11511.     
  11512.     IF EXISTS(select * from sysobjects where type='U' and name = 'MSsubscription_properties')
  11513.     BEGIN
  11514.         DELETE FROM MSsubscription_properties 
  11515.         WHERE UPPER(publisher) = UPPER(@publisher)  AND
  11516.         publisher_db  = @publisher_db AND
  11517.         publication = @publication 
  11518.  
  11519.         IF @@ERROR <> 0 
  11520.             GOTO UNDO
  11521.  
  11522.         IF NOT EXISTS (SELECT * FROM MSsubscription_properties)
  11523.         BEGIN
  11524.             exec @retcode = dbo.sp_MSsub_cleanup_prop_table
  11525.             IF @@ERROR <> 0 or @retcode <> 0
  11526.                 GOTO UNDO
  11527.         END
  11528.     END
  11529.     
  11530.     /*
  11531.     ** Clean up metadata at subscriber side
  11532.     */
  11533.     -- Note: sp_subscription_cleanup should be called after deleting the row
  11534.     -- in MSreplication_subscriptions.
  11535.     exec @retcode = dbo.sp_subscription_cleanup @publisher = @publisher,
  11536.                                             @publisher_db  = @publisher_db,
  11537.                                             @publication = @publication
  11538.     IF @retcode<>0 or @@ERROR<>0
  11539.         GOTO UNDO
  11540.  
  11541.     --
  11542.     -- drop table MSreplication_subscriptions if empty and
  11543.     -- not in recursive call
  11544.     --
  11545.     IF EXISTS (SELECT * 
  11546.                  FROM sysobjects 
  11547.                 WHERE name = 'MSreplication_subscriptions' 
  11548.                   AND type = 'U')
  11549.     BEGIN
  11550.         IF (@reserved = 0 AND 
  11551.             NOT EXISTS (SELECT * FROM MSreplication_subscriptions))
  11552.         BEGIN
  11553.             DROP TABLE MSreplication_subscriptions
  11554.             IF @@ERROR <> 0 
  11555.                 GOTO UNDO
  11556.         END
  11557.     END
  11558.  
  11559.     COMMIT TRAN
  11560.     /*
  11561.     ** set back the two settings if needed 
  11562.     */
  11563.     if @reserved = 0
  11564.     BEGIN
  11565.         IF @implicit_transaction <>0 
  11566.             SET IMPLICIT_TRANSACTIONS ON
  11567.         IF @close_cursor_at_commit <>0 
  11568.             SET CURSOR_CLOSE_ON_COMMIT ON
  11569.     END
  11570.     RETURN (0)
  11571.  
  11572. UNDO:
  11573.     IF @@TRANCOUNT > 0
  11574.     begin
  11575.         ROLLBACK TRAN droppullsubscription
  11576.         COMMIT TRAN   
  11577.     end
  11578.     /*
  11579.     ** set back the two settings if needed
  11580.     */
  11581.     if @reserved = 0
  11582.     BEGIN
  11583.         IF @implicit_transaction <>0 
  11584.             SET IMPLICIT_TRANSACTIONS ON
  11585.         IF @close_cursor_at_commit <>0 
  11586.             SET CURSOR_CLOSE_ON_COMMIT ON
  11587.     END
  11588.  
  11589.     return 1
  11590. go
  11591. exec sp_MS_marksystemobject 'dbo.sp_droppullsubscription'
  11592.  
  11593. raiserror('Creating procedure sp_helppullsubscription', 0,1, 0,1)
  11594. go
  11595.  
  11596. CREATE PROCEDURE sp_helppullsubscription (
  11597.     @publisher sysname = '%',
  11598.     @publisher_db sysname = '%',
  11599.     @publication sysname = '%',
  11600.     @show_push nvarchar(5) = 'false'
  11601.     ) AS
  11602.  
  11603.     SET NOCOUNT ON
  11604.  
  11605.     /*
  11606.     ** Declarations.
  11607.     */
  11608.  
  11609.  
  11610.     DECLARE @command nvarchar(255)
  11611.     DECLARE @name nvarchar(255)
  11612.     DECLARE @retcode int
  11613.     DECLARE @show_push_bit bit
  11614.     DECLARE @push int
  11615.     declare @subscriber            sysname
  11616.     declare @subscriber_db        sysname
  11617.     declare @publisher_local    sysname
  11618.     declare @publisher_db_local    sysname
  11619.     declare @publication_local    sysname
  11620.     declare @subscription_name     nvarchar(1000)
  11621.     declare @regkey                nvarchar(1000)
  11622.     declare @syncmgr_keyexist                int
  11623.     declare @helpsubscriptioncursor_open    int
  11624.  
  11625.  
  11626.     SELECT @push = 0
  11627.  
  11628.     -- For attach
  11629.     if exists (select * from sysobjects where name = 'MSrepl_restore_stage')
  11630.         -- The database is attached from a subscription copy file without using
  11631.         -- sp_attachsubscription. Return nothing
  11632.         return 0
  11633.  
  11634.     /*
  11635.     ** Security Check
  11636.     */
  11637.  
  11638.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  11639.     IF @@ERROR <> 0 or @retcode <> 0
  11640.         RETURN(1)
  11641.  
  11642.     /*
  11643.     ** Initializations.
  11644.     */
  11645.     set @subscriber = @@SERVERNAME     
  11646.     set @subscriber_db = DB_NAME()
  11647.  
  11648.     /*
  11649.     ** Parameter Check: @publisher
  11650.     ** Check to make sure that the publisher is define
  11651.     */
  11652.     IF @publisher IS NULL
  11653.     BEGIN
  11654.         RAISERROR (14043, 16, -1, '@publisher')
  11655.         RETURN (1)
  11656.     END
  11657.  
  11658.     IF @publisher <> '%' 
  11659.     BEGIN
  11660.         EXECUTE @retcode = dbo.sp_validname @publisher
  11661.  
  11662.         IF @@ERROR <> 0 OR @retcode <> 0
  11663.                RETURN (1)
  11664.     END
  11665.  
  11666.     IF @publication <> '%' 
  11667.     BEGIN
  11668.         EXECUTE @retcode = dbo.sp_validname @publication
  11669.  
  11670.         IF @@ERROR <> 0 OR @retcode <> 0
  11671.                RETURN (1)
  11672.     END
  11673.  
  11674.  
  11675.     IF @show_push IS NOT NULL AND 
  11676.         LOWER(@show_push collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('true', 'false')
  11677.     BEGIN
  11678.         RAISERROR (14148, 16, -1, '@show_push')
  11679.         RETURN (1)
  11680.     END
  11681.  
  11682.     IF LOWER(@show_push collate SQL_Latin1_General_CP1_CS_AS) = 'false'                
  11683.         SELECT @show_push_bit = 0    
  11684.     IF LOWER(@show_push collate SQL_Latin1_General_CP1_CS_AS) = 'true'    
  11685.         SELECT @show_push_bit = 1
  11686.  
  11687.  
  11688.     IF NOT EXISTS (SELECT * FROM sysobjects WHERE 
  11689.         type = 'U' AND
  11690.         name = 'MSreplication_subscriptions')
  11691.         RETURN (0)
  11692.  
  11693.     IF NOT EXISTS (SELECT * FROM sysobjects WHERE 
  11694.         type = 'U' AND
  11695.         name = 'MSsubscription_properties')
  11696.         RETURN (0)
  11697.  
  11698.     IF NOT EXISTS (SELECT * FROM sysobjects WHERE 
  11699.         type = 'U' AND
  11700.         name = 'MSsubscription_agents')
  11701.         RETURN (0)
  11702.  
  11703.                 
  11704.     /*
  11705.     ** Get the result
  11706.     **
  11707.     ** Note: have to return meta data
  11708.     */
  11709.         SELECT  'publisher'                = rs.publisher,
  11710.             'publisher database'    = rs.publisher_db,
  11711.             'publication'            = rs.publication,
  11712.             'independent_agent'        = rs.independent_agent,
  11713.             'subscription type'     = rs.subscription_type,
  11714.             'distribution agent'    = distribution_agent,
  11715.             'publication description'   = description,
  11716.             'last updating time'        = convert(nvarchar(12), time, 112) + 
  11717.                                           substring(convert(nvarchar(24), time, 121), 11,13),
  11718.             'subscription_name'          = rs.publisher + ':' + rs.publisher_db + ':' + rs.publication,
  11719.             'last transaction timestamp' = transaction_timestamp,
  11720.             -- SyncTran
  11721.             -- For Queued case, we will return 2/3 for values 4/5 so that
  11722.             -- SQL-DMO does not have to deal with the overloaded values of update_mode
  11723.             'update_mode'         = case     when rs.update_mode = 4 then 2
  11724.                                             when rs.update_mode = 5 then 3
  11725.                                             else rs.update_mode
  11726.                                     end,
  11727.             'distribution agent job_id' = agent_id,
  11728.             'enabled for syncmgr' = enabled_for_syncmgr,
  11729.             'subscription guid' = subscription_guid,
  11730.             'subid ' = subid,
  11731.             'immediate_sync' = immediate_sync,
  11732.             'publisher_login' = publisher_login,
  11733.             'publisher_password' = publisher_password,
  11734.             'publisher_security_mode' = publisher_security_mode,
  11735.             'distributor' = distributor,
  11736.             'distributor_login' = distributor_login,
  11737.             'distributor_password' = distributor_password,
  11738.             'distributor_security_mode' = distributor_security_mode,
  11739.             'ftp_address' = ftp_address,
  11740.             'ftp_port' = ftp_port,
  11741.             'ftp_login' = ftp_login,
  11742.             'ftp_password' = ftp_password,
  11743.             'alt_snapshot_folder' = alt_snapshot_folder,
  11744.             'working_directory' = working_directory,
  11745.             'use_ftp' = use_ftp,
  11746.             'publication_type' = publication_type,
  11747.             'dts_package_name' = dts_package_name,
  11748.             'dts_package_location' = dts_package_location,
  11749.             'offload_agent' = offload_agent,
  11750.             'offload_server' = offload_server,
  11751.             a.last_sync_status, 
  11752.             a.last_sync_summary,
  11753.             'last_sync_time' = convert(nvarchar(12), a.last_sync_time, 112) + 
  11754.                 substring(convert(nvarchar(24), a.last_sync_time, 121), 11,13)
  11755.        from MSreplication_subscriptions rs
  11756.        left outer join MSsubscription_properties sp 
  11757.                     on (UPPER(rs.publisher) = UPPER(sp.publisher) and rs.publisher_db = sp.publisher_db and rs.publication = sp.publication) 
  11758.        left outer join MSsubscription_agents a
  11759.                     on (UPPER(rs.publisher) = UPPER(a.publisher) and 
  11760.                         rs.publisher_db = a.publisher_db and 
  11761.                         ((rs.publication = a.publication and 
  11762.                         rs.independent_agent = 1 and
  11763.                         a.publication <> N'ALL') or
  11764.                         (a.publication = N'ALL' and rs.independent_agent = 0)) and
  11765.                         rs.subscription_type = a.subscription_type)
  11766.                 where ((@publisher = N'%') OR (UPPER(rs.publisher) = UPPER(@publisher))) AND
  11767.                       ((@publisher_db = N'%') OR (rs.publisher_db = @publisher_db)) AND
  11768.                       ((@publication = N'ALL' AND rs.independent_agent = 0) OR rs.publication LIKE @publication) AND
  11769.                       (rs.subscription_type <> @push OR
  11770.                        @show_push_bit = 1)
  11771.         ORDER BY rs.publisher, rs.publisher_db, rs.publication  
  11772. GO
  11773.  
  11774.  
  11775. raiserror('Creating procedure sp_MStable_has_unique_index', 0,1)
  11776. go
  11777.  
  11778. create procedure sp_MStable_has_unique_index @tabid int
  11779. as
  11780. begin
  11781.  
  11782.     /* 
  11783.     ** Returns id of unique index, if it exists, else 0
  11784.     */
  11785.     declare @indid int
  11786.  
  11787.     if (ObjectProperty(@tabid, 'IsTable') = 1) and (ObjectProperty(@tabid, 'TableHasIndex') = 1)
  11788.     begin
  11789.         -- First get the primary index id. 
  11790.         select @indid = i.indid from sysindexes i where 
  11791.             -- get the primary key index
  11792.             (i.status & 2048) <> 0
  11793.             and i.id = @tabid
  11794.  
  11795.         if @indid is null
  11796.         begin
  11797.             -- Get the first unique index
  11798.             select top 1 @indid = i.indid from sysindexes i where 
  11799.                 (i.status & 2) <> 0
  11800.                 and i.id = @tabid
  11801.                 order by i.indid asc
  11802.         end
  11803.         if @indid is null select @indid = 0
  11804.     end
  11805.     else
  11806.         select @indid = 0
  11807.  
  11808.     return @indid
  11809. end
  11810. go
  11811.  
  11812. raiserror('Creating procedure sp_MSchange_retention', 0,1)
  11813. GO
  11814.  
  11815. CREATE PROCEDURE sp_MSchange_retention (@pubid uniqueidentifier, @value nvarchar(255))
  11816. as
  11817.     declare @re_pubid            uniqueidentifier 
  11818.     declare @artid                uniqueidentifier
  11819.     declare @schemaversion      int 
  11820.     declare @schemaguid         uniqueidentifier
  11821.     declare @schematype         int
  11822.     declare @schematext         nvarchar(2000)
  11823.     declare @retcode            int
  11824.  
  11825.     -- Security check
  11826.     if  1 <> {fn ISPALUSER(@pubid)}  
  11827.     begin
  11828.         raiserror(15247,-1,-1)
  11829.         return 1
  11830.     end
  11831.  
  11832.     begin TRAN    
  11833.         update sysmergepublications set retention = convert(int, @value) where pubid = @pubid
  11834.         if @@ERROR<>0
  11835.             goto UNDO
  11836.             
  11837.         declare #change_retention CURSOR LOCAL FAST_FORWARD fast_forward for 
  11838.             select pubid from sysmergearticles where pubid<>@pubid and nickname in
  11839.                 (select nickname from sysmergearticles where pubid=@pubid)
  11840.         open #change_retention
  11841.         fetch #change_retention into @re_pubid
  11842.         while (@@fetch_status <> -1)
  11843.         BEGIN
  11844.             update sysmergepublications set retention = convert(int, @value) where pubid = @re_pubid
  11845.             if @@ERROR<>0
  11846.                 goto UNDO
  11847.             set @schematype = 9 /* change retention */
  11848.             set @artid = newid()
  11849.             select @schematext = 'exec dbo.sp_MSchange_retention '+ '''' + convert(nchar(36),@re_pubid) + '''' + ',' + '''' + @value + ''''          
  11850.             select @schemaversion = schemaversion from sysmergeschemachange
  11851.             if (@schemaversion is NULL)
  11852.                 set @schemaversion = 1
  11853.             else
  11854.                 select @schemaversion = 1 + max(schemaversion) from sysmergeschemachange        
  11855.             set @schemaguid = newid()
  11856.             exec @retcode=sp_MSinsertschemachange @re_pubid, @artid, @schemaversion, @schemaguid, @schematype, @schematext
  11857.             if @@ERROR<>0 or @retcode<>0 
  11858.                 goto UNDO
  11859.             fetch #change_retention into @re_pubid
  11860.         END
  11861.         close #change_retention
  11862.         deallocate #change_retention
  11863.     COMMIT TRAN
  11864.     return (0)
  11865. UNDO:
  11866.     if @@TRANCOUNT = 1
  11867.         ROLLBACK TRAN
  11868.     else
  11869.         COMMIT TRAN
  11870.     return(1)
  11871. GO
  11872. exec dbo.sp_MS_marksystemobject sp_MSchange_retention 
  11873. go
  11874. grant execute on dbo.sp_MSchange_retention to public
  11875.  
  11876.  
  11877. raiserror('Creating procedure sp_MSchange_priority', 0,1)
  11878. GO
  11879. -- @value has to be unicode too.
  11880.  
  11881. CREATE PROCEDURE sp_MSchange_priority (@subid uniqueidentifier, @value nvarchar(255))
  11882. as
  11883.     declare @retcode int
  11884.     exec @retcode = dbo.sp_MSreplcheck_subscribe
  11885.     if @retcode <> 0 or @@error <> 0
  11886.         return 1
  11887.         
  11888.     update sysmergesubscriptions set priority = convert(real, @value)
  11889.            where subid = @subid
  11890. go
  11891. exec dbo.sp_MS_marksystemobject sp_MSchange_priority 
  11892. go
  11893. grant execute on dbo.sp_MSchange_priority to public
  11894.  
  11895. raiserror('Creating procedure sp_expired_subscription_cleanup', 0,1)
  11896. GO
  11897.  
  11898. CREATE PROCEDURE sp_expired_subscription_cleanup
  11899. AS
  11900. declare @retcode         int
  11901. declare @publisher_db    sysname
  11902. declare @category        int
  11903. declare @proc_name        nvarchar(200)
  11904. declare @distributor     sysname
  11905. declare @distribdb        sysname
  11906. declare @distproc        nvarchar(300)
  11907. /*
  11908. ** Security Check
  11909. */
  11910.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  11911.     IF @@ERROR <> 0 or @retcode <> 0
  11912.         return (1)
  11913.     /*
  11914.     ** Get distribution server information for remote RPC call.
  11915.     */
  11916.  
  11917. EXECUTE @retcode = sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  11918.      @distribdb   = @distribdb OUTPUT
  11919. IF @@ERROR <> 0 or @retcode <> 0
  11920.     BEGIN
  11921.         RAISERROR (20036, 16, -1)
  11922.         return (1)
  11923.     END
  11924.     
  11925.         
  11926. DECLARE DC CURSOR LOCAL FAST_FORWARD for select DISTINCT name, category from master..sysdatabases 
  11927.     where (category & 4) = 4 or (category & 1 = 1)
  11928.     for read only
  11929.     open DC
  11930.     fetch DC into @publisher_db, @category
  11931.     WHILE (@@fetch_status <> -1)
  11932.     BEGIN
  11933.         if (@category & 4 = 4)
  11934.             begin
  11935.                 select @proc_name = @publisher_db + '.dbo.sp_MSdrop_expired_mergesubscription'
  11936.                 exec @retcode = @proc_name
  11937.                 if @retcode<>0 or @@ERROR<>0
  11938.                     goto DONE
  11939.             end
  11940.         if (@category & 1 = 1)
  11941.             begin
  11942.                 select @proc_name = @publisher_db + '.dbo.sp_MSdrop_expired_subscription'
  11943.                 exec @retcode = @proc_name
  11944.                 if @retcode<>0 or @@ERROR<>0
  11945.                     goto DONE
  11946.             end    
  11947.     fetch DC into @publisher_db, @category
  11948.     END
  11949.  
  11950.     /*
  11951.     ** sp_MScleanup_agent_entry in distribution database is called to periodically remove obselete
  11952.     ** entries in MSmerge_agents, which may be caused by the following reasons:
  11953.     **  1. publishing database is externally removed; therefore cleanup agent can not do its job
  11954.     **  2. Entries for anonymous merge subscriptions
  11955.     */
  11956.     SELECT @distproc = RTRIM(@distributor) + '.' + RTRIM(@distribdb) + '..sp_MScleanup_agent_entry'
  11957.     exec @retcode = @distproc 
  11958.     if @@ERROR<>0 or @retcode<>0
  11959.     BEGIN
  11960.         close DC
  11961.         deallocate DC
  11962.         return (1)
  11963.     END
  11964.  
  11965. DONE:
  11966.     close DC
  11967.     deallocate DC
  11968. GO
  11969.  
  11970. go
  11971. exec dbo.sp_MS_marksystemobject sp_expired_subscription_cleanup
  11972. go
  11973. grant execute on dbo.sp_expired_subscription_cleanup to public
  11974.  
  11975.  
  11976. raiserror('Creating procedure sp_addmergepullsubscription', 0,1)
  11977. GO
  11978.  
  11979. CREATE PROCEDURE sp_addmergepullsubscription (
  11980.     @publication                 sysname,                      /* Publication name */
  11981.     @publisher                    sysname = @@SERVERNAME,      /* Publisher server */
  11982.     @publisher_db                sysname = NULL,              /* Publication database */
  11983.     @subscriber_type             nvarchar(15) = 'local',            /* Subscriber type */ 
  11984.     @subscription_priority         real         = NULL,                /* Subscription priority */
  11985.     @sync_type                     nvarchar(15) = 'automatic', /* subscription sync type */
  11986.     @description                 nvarchar(255) = NULL              
  11987.      ) AS
  11988.  
  11989.     SET NOCOUNT ON
  11990.  
  11991.     /*
  11992.     ** Declarations.
  11993.     */
  11994.     declare @retcode                int
  11995.     declare    @subscriber_db            sysname
  11996.     declare @subnickname            int
  11997.     declare @subscriber_srvid        int 
  11998.     declare @publisher_srvid        int 
  11999.     declare @priority                 real
  12000.     declare @subid                     uniqueidentifier
  12001.     declare @subscriber_typeid         smallint
  12002.     declare @subscription_type         smallint
  12003.     declare @command                 nvarchar(255)
  12004.     declare @inactive                tinyint 
  12005.     declare @global                 tinyint        /* subscriber type is global */
  12006.     declare @push                     tinyint        /* subscription type is push */
  12007.      
  12008.     declare @sync_typeid             tinyint
  12009.     declare @nosync                 tinyint        
  12010.     declare @automatic                tinyint             
  12011.     declare @pubid                    uniqueidentifier             
  12012.     declare @partnerid                uniqueidentifier             
  12013.     declare @parentid               uniqueidentifier
  12014.  
  12015.     /*
  12016.     ** Initializations.
  12017.     */
  12018.  
  12019.     SET @nosync             = 2       /* Const: synchronization type 'none' */
  12020.     SET @automatic             = 1       /* Const: synchronization type 'automatic' */
  12021.     SET @inactive             = 0
  12022.     SET @global             = 1
  12023.     SET @push                 = 0   
  12024.  
  12025.  
  12026.     set @pubid                 = newid()
  12027.     set @partnerid            = @pubid
  12028.     
  12029.     set @parentid            = '00000000-0000-0000-0000-000000000000'
  12030.      
  12031.     /* 
  12032.     ** Check if replication components are installed on this server
  12033.     */
  12034.     exec @retcode = dbo.sp_MS_replication_installed
  12035.     if (@retcode <> 1)
  12036.     begin
  12037.         return (1)
  12038.     end
  12039.  
  12040.     /*
  12041.     ** Security Check.
  12042.     */
  12043.  
  12044.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  12045.     if @@ERROR <> 0 or @retcode <> 0
  12046.         return(1)
  12047.  
  12048.     /*
  12049.     **    Check to see if merge system tables exist. Create them unless they already
  12050.     **  exist.
  12051.     */
  12052.     IF not exists (select name from sysobjects where name='sysmergesubscriptions')
  12053.         BEGIN
  12054.             execute @retcode = dbo.sp_MScreate_mergesystables
  12055.                 if @@ERROR <> 0 or @retcode <> 0
  12056.                     begin
  12057.                         return (1)
  12058.                     end
  12059.         END    
  12060.  
  12061.     if UPPER(@publisher) = UPPER(@@SERVERNAME) and @publisher_db = db_name()
  12062.         begin
  12063.             raiserror(21126, 16, -1)
  12064.             return (1)
  12065.         end
  12066.  
  12067.     if exists (select pubid from sysmergepublications where UPPER(publisher) = UPPER(@@SERVERNAME) and publisher_db=db_name()) and @subscriber_type in ('local', 'anonymous')
  12068.         begin
  12069.             declare @dbname sysname
  12070.             select @dbname = DB_NAME()
  12071.             raiserror(21258, 16, -1, @dbname)
  12072.             return (1)
  12073.         end
  12074.     /* 
  12075.     ** When adding a pull subscription, if a push subscription for that publication already exists, 
  12076.     ** we will raise error and fail
  12077.     */
  12078.     IF EXISTS (select name from sysmergepublications where name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db)
  12079.     BEGIN
  12080.         select @pubid=pubid from sysmergepublications 
  12081.             where name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db
  12082.         IF EXISTS (select subid from sysmergesubscriptions where pubid=@pubid and subid<>@pubid and subscription_type=0)
  12083.             begin
  12084.                 RAISERROR (21317, 16, -1, @publication)
  12085.                 return (1)
  12086.             end
  12087.         ELSE
  12088.             begin
  12089.                 IF EXISTS (select status from sysmergesubscriptions where pubid=@pubid and status =    2)
  12090.                     begin
  12091.                         select @subid = subid from sysmergesubscriptions where pubid=@pubid and subid<>pubid
  12092.                         delete sysmergesubscriptions where pubid=@pubid
  12093.                         delete MSmerge_replinfo where repid = @subid
  12094.                     end
  12095.                 ELSE 
  12096.                     begin
  12097.                         RAISERROR (14058, 16, -1)
  12098.                         return (1)
  12099.                     end
  12100.             end
  12101.     END
  12102.  
  12103.     set @partnerid = @pubid
  12104.      
  12105.       /*
  12106.     ** Assign parameter values appropriately for the local server database
  12107.     */
  12108.     set @subscriber_db = DB_NAME()
  12109.     select @subscriber_srvid = 0
  12110.  
  12111.     /*
  12112.     ** Parameter Check: @publisher
  12113.     ** Check to make sure that the publisher is defined
  12114.     */
  12115.     IF @publisher IS NULL
  12116.     BEGIN
  12117.         RAISERROR (14043, 16, -1, '@publisher')
  12118.         RETURN (1)
  12119.     END
  12120.  
  12121.     IF LOWER(@publisher) = 'all'
  12122.     BEGIN
  12123.         RAISERROR (14136, 16, -1)
  12124.         RETURN (1)
  12125.     END
  12126.  
  12127.     EXECUTE @retcode = dbo.sp_validname @publisher
  12128.     IF @@ERROR <> 0 OR @retcode <> 0
  12129.        RETURN (1)
  12130.     /*
  12131.     ** Validate that the publisher is a valid server
  12132.     */
  12133.     select @publisher_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher) collate database_default
  12134.     IF @publisher_srvid IS NULL
  12135.         BEGIN
  12136.             EXECUTE @retcode = dbo.sp_addserver @publisher
  12137.             IF @@error <> 0 OR @retcode <> 0
  12138.                 BEGIN
  12139.                     RAISERROR (14010, 16, -1)
  12140.                        RETURN (1)
  12141.                 END
  12142.             ELSE
  12143.                 select @publisher_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher) collate database_default
  12144.         END
  12145.  
  12146.  
  12147.     /*
  12148.     ** Parameter Check: @publisher_db
  12149.     */
  12150.     IF @publisher_db IS NULL
  12151.     BEGIN
  12152.         RAISERROR (14043, 16, -1, '@publisher_db')
  12153.         RETURN (1)
  12154.     END
  12155.  
  12156.     IF LOWER(@publisher_db) = 'all'
  12157.     BEGIN
  12158.         RAISERROR (14136, 16, -1)
  12159.         RETURN (1)
  12160.     END
  12161.     
  12162.     /*
  12163.     ** Check to see if the publication name is already used in the subscription 
  12164.     ** database - This is the case where we are resubscribing to the same publication.
  12165.     ** Execute dbo.sp_MSpublicationcleanup to cleanup all all the defunct rows
  12166.     
  12167.     ** if exists (select * from sysmergepublications where name = @publication)
  12168.     ** begin
  12169.     **    exec @retcode = dbo.sp_MSpublicationcleanup 
  12170.     **    IF @@ERROR <> 0 OR @retcode <> 0
  12171.     **        BEGIN
  12172.     **            RAISERROR (20025, 16, -1, @publication)
  12173.     **            RETURN (1)
  12174.     **        END                        
  12175.     ** end
  12176.     */
  12177.  
  12178.     /*
  12179.     ** Parameter Check: @subscriber_type.
  12180.     ** Set subscriber_typeid based on the @subscriber_type specified.
  12181.     **
  12182.     **   subscriber_type     subscriber_type
  12183.     **   =================    ===============
  12184.     **             1             global
  12185.     **             2             local
  12186.     **             3             anonymous
  12187.     **             NO support for republisher for B 3
  12188.     */
  12189.     if LOWER(@subscriber_type collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('local', 'global', 'anonymous')
  12190.         BEGIN
  12191.               RAISERROR (20023, 16, -1)
  12192.             RETURN (1)
  12193.         END
  12194.  
  12195.     set @subscription_type = 1 /* pull by default */
  12196.     if LOWER(@subscriber_type collate SQL_Latin1_General_CP1_CS_AS) IN ('global')
  12197.         set @subscriber_typeid = 1
  12198.     else if LOWER(@subscriber_type collate SQL_Latin1_General_CP1_CS_AS) IN ('local')
  12199.         set @subscriber_typeid = 2
  12200.     else if LOWER(@subscriber_type collate SQL_Latin1_General_CP1_CS_AS) IN ('anonymous')       
  12201.         begin
  12202.             /* For anonymous subscribers set subscription type appropriately */
  12203.             set @subscriber_typeid = 3
  12204.             set @subscription_type = 2
  12205.         end            
  12206.  
  12207.     /* 
  12208.     ** Assign priority appropriately - choose 0.99 times the minimum priority
  12209.     ** of the global replicas.
  12210.     */
  12211.     if (@subscription_priority > 100.0 or @subscription_priority < 0.0)
  12212.         set @subscription_priority = NULL        
  12213.     if (@subscription_priority IS NULL)
  12214.         begin
  12215.             select @priority = 0.99 * min(priority) from sysmergesubscriptions where subscriber_type  = 1 /* global/loopback */
  12216.             if (@priority IS NOT NULL)
  12217.                 select @subscription_priority = @priority
  12218.             if (@subscription_priority IS NULL) 
  12219.                 select @subscription_priority = 0.0
  12220.         end
  12221.     /*
  12222.     ** For local and anonymous subscriptions the priority is 0.0
  12223.     */
  12224.     if LOWER(@subscriber_type collate SQL_Latin1_General_CP1_CS_AS) IN ('local', 'anonymous')
  12225.         select @subscription_priority = 0.0
  12226.  
  12227.     /*
  12228.      ** If the subscription already exists, don't add it.
  12229.     
  12230.      ** if EXISTS (select db_name, srvid
  12231.      **        FROM sysmergesubscriptions
  12232.     **         WHERE db_name = @subscriber_db
  12233.     **         AND srvid = @subscriber_srvid                           
  12234.     **        AND pubid = @pubid)
  12235.     **    BEGIN
  12236.     **        RAISERROR (14058, 16, -1)
  12237.     **        RETURN (1)
  12238.      **    END
  12239.     */
  12240.  
  12241.    /*
  12242.    ** Parameter Check: @sync_type.
  12243.    ** Set sync_typeid based on the @sync_type specified.
  12244.    **
  12245.    **   sync_typeid     sync_type
  12246.    **   ===========     =========
  12247.    **             1     automatic
  12248.    **             2     none
  12249.    */
  12250.  
  12251.  
  12252.    IF LOWER(@sync_type collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('automatic', 'none')
  12253.        BEGIN
  12254.            RAISERROR (14052, 16, -1)
  12255.            RETURN (1)
  12256.        END
  12257.  
  12258.  
  12259.    IF LOWER(@sync_type collate SQL_Latin1_General_CP1_CS_AS) = 'automatic'
  12260.    BEGIN
  12261.         SET @sync_typeid = @automatic
  12262.    END
  12263.    ELSE
  12264.    BEGIN
  12265.         SET @sync_typeid = @nosync
  12266.    END
  12267.  
  12268.  
  12269.     /*
  12270.     ** UNDONE: Validate that the publisher is of type 'republisher'
  12271.     */
  12272.  
  12273.     begin tran
  12274.     save TRAN addmergepullsubscription
  12275.         
  12276.         /* Generate a guid for the Subscriber ID */
  12277.         set @subid = newid()
  12278.  
  12279.         /* Look for existing nickname from any other subscription */
  12280.         exec dbo.sp_MSgetreplnick NULL, NULL , NULL,  @subnickname out
  12281.         if (@@error <> 0) 
  12282.             begin
  12283.             goto FAILURE
  12284.             end                 
  12285.  
  12286.  
  12287.         /* Generate a new replica nickname from the @subid */
  12288.         if (@subnickname is null)
  12289.             EXECUTE dbo.sp_MSgenreplnickname @subid, @subnickname output
  12290.  
  12291.     
  12292.         /* 
  12293.         ** Check to see if MSsubscription_properties table exists.
  12294.         ** If not, create it.
  12295.         */
  12296.         exec @retcode = dbo.sp_MScreate_sub_tables
  12297.             @tran_sub_table = 0,
  12298.             @property_table = 1,
  12299.             @sqlqueue_table = 0
  12300.  
  12301.         IF @@ERROR <> 0 or @retcode <> 0
  12302.             goto FAILURE
  12303.  
  12304.         /*
  12305.         ** The subscription doesn't exist, so let's add it to sysmergesubscriptions 
  12306.         */
  12307.         INSERT sysmergesubscriptions (subid, partnerid, datasource_type, srvid, db_name, 
  12308.                 pubid, status, subscriber_type, subscription_type, priority, sync_type, 
  12309.                 description, login_name, subscriber_server, publication)
  12310.                     VALUES (@subid,
  12311.                             @partnerid,
  12312.                             0,
  12313.                             @subscriber_srvid,
  12314.                             @subscriber_db,
  12315.                             @pubid,
  12316.                             @inactive,
  12317.                             @subscriber_typeid,
  12318.                             @subscription_type,     /* for a pull/anon subscription */
  12319.                             @subscription_priority,
  12320.                             @sync_typeid,
  12321.                             @description,
  12322.                             suser_sname(suser_sid()),
  12323.                             @@servername,
  12324.                             @publication)            
  12325.         if @@ERROR <> 0
  12326.             BEGIN
  12327.                 GOTO FAILURE
  12328.             END
  12329.  
  12330.         /* Add a self-subscribed subscription to represent the publication */
  12331.             
  12332.         insert sysmergepublications(publisher, publisher_db, pubid, name, parentid) 
  12333.             values(@publisher, @publisher_db, @pubid, @publication, @parentid)
  12334.         if @@ERROR <> 0
  12335.             begin
  12336.                 goto FAILURE
  12337.             end
  12338.         insert sysmergesubscriptions(subid, partnerid, datasource_type, srvid, db_name, 
  12339.                 pubid, subscriber_type, subscription_type, status, priority, sync_type, description, login_name, subscriber_server, publication, distributor)
  12340.             values (@pubid, @pubid, 0, @publisher_srvid, @publisher_db, 
  12341.                 @pubid, @global, @push, @inactive, 100.0, @sync_typeid, @description, suser_sname(suser_sid()), @publisher, @publication, @publisher)  
  12342.                         
  12343.         if @@ERROR <> 0
  12344.             begin
  12345.                 goto FAILURE
  12346.             end
  12347.                     
  12348.         /*
  12349.         **  Add row for subscription in MSmerge_replinfo.
  12350.         */
  12351.         insert MSmerge_replinfo(repid, replnickname)
  12352.                 values (@subid, @subnickname)
  12353.         if @@ERROR <> 0
  12354.             BEGIN
  12355.                 GOTO FAILURE
  12356.             END
  12357.  
  12358.     COMMIT TRAN
  12359.     return (0)
  12360.  
  12361. FAILURE:
  12362.     RAISERROR (14057, 16, -1)
  12363.     if @@trancount > 0
  12364.     begin
  12365.         ROLLBACK TRANSACTION addmergepullsubscription
  12366.         COMMIT TRANSACTION
  12367.     end
  12368.     RETURN (1)
  12369.  
  12370. go
  12371. exec dbo.sp_MS_marksystemobject sp_addmergepullsubscription 
  12372. go
  12373.  
  12374. grant execute on dbo.sp_addmergepullsubscription to public
  12375. go
  12376.  
  12377. raiserror('Creating procedure sp_changemergepullsubscription', 0,1)
  12378. GO
  12379.  
  12380. CREATE PROCEDURE sp_changemergepullsubscription (
  12381.     @publication         sysname = '%',    /* Publication name */
  12382.     @publisher            sysname = '%',  /* Publisher server */
  12383.     @publisher_db        sysname = '%',     /* Publication database */
  12384.     @property             sysname = NULL, /* The property to change */
  12385.     @value                 nvarchar(255) = NULL    /* The new property value */
  12386.     ) AS
  12387.  
  12388.     SET NOCOUNT ON
  12389.  
  12390.     /*
  12391.     ** Declarations.
  12392.     */
  12393.     declare @subscriber_srvid         int
  12394.     declare @publisher_srvid         int
  12395.     declare @retcode                 int
  12396.     declare    @pubid                     uniqueidentifier
  12397.     declare    @subid                     uniqueidentifier
  12398.     declare    @partnerid                 uniqueidentifier
  12399.     declare @sync_typeid             tinyint
  12400.     declare @nosync                 tinyint
  12401.     declare @automatic                 tinyint
  12402.      
  12403.     declare @artid                    uniqueidentifier
  12404.     declare @subscriber                sysname
  12405.     declare @subscriber_db            sysname
  12406.     declare @schematype                int
  12407.     declare @schemaversion            int
  12408.     declare @schemaguid                uniqueidentifier
  12409.     declare @db_name                sysname
  12410.     declare @subscriber_type        int
  12411.     declare @schematext                nvarchar(2000)
  12412.     declare @use_interactive_bit    bit
  12413.     declare @use_interactive_int    int
  12414.     declare @enabled_for_syncmgr    int
  12415.     declare @regkey                    nvarchar(1000)
  12416.     declare @snapshot_ready            int
  12417.     /*
  12418.     ** Initializations.
  12419.     */
  12420.     SET @subscriber     = @@SERVERNAME
  12421.     SET @subscriber_db    = DB_NAME()
  12422.     SET @nosync         = 2     /* Const: synchronization type 'none' */
  12423.     SET @automatic         = 1     /* Const: synchronization type 'automatic' */
  12424.  
  12425.     select @subscriber_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber) collate database_default
  12426.     IF @subscriber_srvid IS NULL
  12427.         BEGIN
  12428.            RAISERROR (14010, 16, -1)
  12429.            RETURN (1)     
  12430.         END
  12431.  
  12432.     /*
  12433.     ** Security Check.
  12434.     */
  12435.     BEGIN
  12436.         exec @retcode = dbo.sp_MSreplcheck_subscribe
  12437.         if @@ERROR <> 0 or @retcode <> 0
  12438.             return(1)
  12439.     END
  12440.  
  12441.  
  12442.     /*
  12443.     **    Check to see if current database is enabled for subscribing
  12444.     */
  12445.     IF not exists (select name from sysobjects where name='sysmergesubscriptions')
  12446.         BEGIN
  12447.             RAISERROR (14055, 16, -1)
  12448.             RETURN (1)
  12449.         END
  12450.  
  12451.     
  12452.     /*
  12453.     ** Parameter Check:  @property.
  12454.     ** If the @property parameter is NULL, print the options.
  12455.     */
  12456.  
  12457.     IF @property IS NULL
  12458.         BEGIN
  12459.             CREATE TABLE #tab1 (properties sysname collate database_default not null)
  12460.             INSERT INTO #tab1 VALUES ('sync_type')
  12461.             INSERT INTO #tab1 VALUES ('priority')
  12462.             INSERT INTO #tab1 VALUES ('description') 
  12463.             INSERT INTO #tab1 VALUES ('use_interactive_resolver')             
  12464.             -- Properties delegated to sp_change_subscription_properties
  12465.             INSERT INTO #tab1 VALUES ('publisher_login')
  12466.             INSERT INTO #tab1 VALUES ('publisher_password')
  12467.             INSERT INTO #tab1 VALUES ('publisher_security_mode')
  12468.             INSERT INTO #tab1 VALUES ('distributor')
  12469.             INSERT INTO #tab1 VALUES ('distributor_login')
  12470.             INSERT INTO #tab1 VALUES ('distributor_password')
  12471.             INSERT INTO #tab1 VALUES ('distributor_security_mode')
  12472.             INSERT INTO #tab1 VALUES ('ftp_address')
  12473.             INSERT INTO #tab1 VALUES ('ftp_port')
  12474.             INSERT INTO #tab1 VALUES ('ftp_login')
  12475.             INSERT INTO #tab1 VALUES ('ftp_password')
  12476.             INSERT INTO #tab1 VALUES ('alt_snapshot_folder')
  12477.             INSERT INTO #tab1 VALUES ('working_directory')
  12478.             INSERT INTO #tab1 VALUES ('use_ftp')
  12479.             INSERT INTO #tab1 VALUES ('offload_agent')
  12480.             INSERT INTO #tab1 VALUES ('offload_server')
  12481.             INSERT INTO #tab1 VALUES ('dynamic_snapshot_location')
  12482.             select * FROM #tab1
  12483.             RETURN (0)
  12484.         END
  12485.  
  12486.     /*
  12487.     ** Parameter Check:  @publisher.
  12488.     ** Check to make sure we have a valid publisher.
  12489.     ** Should make sure that @publisher is non-null before using it to check whether @publication is valid
  12490.     */
  12491.     IF @publisher IS NULL
  12492.         BEGIN
  12493.             RAISERROR (14043, 16, -1, '@publisher')
  12494.             RETURN (1)
  12495.         END
  12496.  
  12497.     /*
  12498.     ** Parameter Check:  @publication.
  12499.     ** Make sure that the publication exists.
  12500.     */
  12501.  
  12502.     IF @publication IS NULL
  12503.         BEGIN
  12504.             RAISERROR (14043, 16, -1, '@publication')
  12505.             RETURN (1)
  12506.         END
  12507.  
  12508.     select @pubid = pubid FROM sysmergepublications WHERE name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db
  12509.     IF @pubid IS NULL
  12510.         BEGIN
  12511.             RAISERROR (20026, 11, -1, @publication)
  12512.             RETURN (1)
  12513.         END
  12514.  
  12515.     /*
  12516.     ** Validate that the publisher is a valid server
  12517.     */
  12518.     select @publisher_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher) collate database_default
  12519.     IF @publisher_srvid IS NULL
  12520.         BEGIN
  12521.             RAISERROR (14010, 16, -1)
  12522.                RETURN (1)
  12523.         END
  12524.  
  12525.     /*
  12526.     ** Check to see if you have a local / global subscription on this publication
  12527.     */
  12528.     set @subid = NULL
  12529.     select @subid = subs1.subid, 
  12530.     @pubid = pubs.pubid, /* identified from publication name */
  12531.     @subscriber_type=subs1.subscriber_type,
  12532.         @partnerid = subs2.subid from
  12533.         sysmergesubscriptions     subs1,
  12534.           sysmergesubscriptions     subs2,
  12535.         sysmergepublications     pubs
  12536.         where subs1.srvid = @subscriber_srvid
  12537.             and subs1.db_name = @subscriber_db
  12538.             and subs2.srvid = @publisher_srvid
  12539.             and subs2.db_name = @publisher_db
  12540.             and subs1.pubid = subs2.subid
  12541.             and subs2.pubid = pubs.pubid
  12542.             and pubs.name = @publication
  12543.             and UPPER(pubs.publisher)=UPPER(@publisher)
  12544.             and pubs.publisher_db = @publisher_db
  12545.  
  12546.     if @subid IS NULL 
  12547.          begin
  12548.             RAISERROR (14050, 11, -1)
  12549.             RETURN(1)
  12550.         end                 
  12551.  
  12552.     /*
  12553.     ** Parameter Check:  @property.
  12554.     ** Check to make sure that @property is a valid property in
  12555.     ** a merge pull subscription.
  12556.     */
  12557.  
  12558.     
  12559.     IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) NOT IN 
  12560.                                ('sync_type', 
  12561.                                 'priority', 
  12562.                                 'description',
  12563.                                 'publisher_login',
  12564.                                 'publisher_password',
  12565.                                 'publisher_security_mode',
  12566.                                 'distributor',
  12567.                                 'distributor_login',
  12568.                                 'distributor_password',
  12569.                                 'distributor_security_mode',
  12570.                                 'ftp_address',
  12571.                                 'ftp_port',
  12572.                                 'ftp_login',
  12573.                                 'ftp_password',
  12574.                                 'alt_snapshot_folder',
  12575.                                 'working_directory',
  12576.                                 'use_ftp',
  12577.                                 'use_interactive_resolver',
  12578.                                 'offload_agent',
  12579.                                 'offload_server',
  12580.                                 'dynamic_snapshot_location')
  12581.         BEGIN
  12582.             RAISERROR (21348, 16, -1, @property)
  12583.             RETURN (1)
  12584.         END
  12585.  
  12586.     /*
  12587.     ** Change the property.
  12588.     */
  12589.     IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = 'sync_type'
  12590.         BEGIN
  12591.  
  12592.             /*
  12593.             ** Check to make sure that we have a valid sync_type.
  12594.             */
  12595.  
  12596.             IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('automatic', 'none')
  12597.                 BEGIN
  12598.                     RAISERROR (14052, 16, -1)
  12599.                     RETURN (1)
  12600.                 END
  12601.  
  12602.             /*
  12603.             ** Determine the integer value for the sync_type.
  12604.             */
  12605.  
  12606.             IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) = 'automatic'
  12607.                 SET @sync_typeid = @automatic
  12608.             ELSE
  12609.                 SET @sync_typeid = @nosync
  12610.  
  12611.             /*
  12612.             ** Update the subscription with the new sync_type.
  12613.             */
  12614.  
  12615.             UPDATE sysmergesubscriptions
  12616.                    SET sync_type = @sync_typeid
  12617.                  WHERE subid = @subid
  12618.             IF @@ERROR <> 0
  12619.                 BEGIN
  12620.                     RAISERROR (14053, 16, -1)
  12621.                     RETURN (1)
  12622.                 END
  12623.  
  12624.         END
  12625.         
  12626.     IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = 'description'
  12627.         BEGIN
  12628.         UPDATE sysmergesubscriptions
  12629.                    SET description = @value
  12630.                  WHERE subid = @subid
  12631.             IF @@ERROR <> 0
  12632.                 BEGIN
  12633.                     RAISERROR (14053, 16, -1) 
  12634.               
  12635.                     RETURN (1)
  12636.                 END
  12637.  
  12638.         END
  12639.  
  12640.     IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = 'use_interactive_resolver'
  12641.         BEGIN
  12642.  
  12643.             /* Check to make sure that we have a true/false. */
  12644.  
  12645.             IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('true', 'false')
  12646.                 BEGIN
  12647.                     RAISERROR (14148, 16, -1, 'use_interactive_resolver')
  12648.                     RETURN (1)
  12649.                 END
  12650.  
  12651.             /* Determine the bit value. */
  12652.  
  12653.             IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) = 'true'
  12654.                 SET @use_interactive_bit = 1
  12655.             ELSE
  12656.                 SET @use_interactive_bit = 0
  12657.     
  12658.             /* Update the subscription with the new 'use_interactive' value. */
  12659.  
  12660.             UPDATE sysmergesubscriptions
  12661.                    SET use_interactive_resolver = @use_interactive_bit
  12662.                  WHERE subid = @subid
  12663.             IF @@ERROR <> 0
  12664.                 BEGIN
  12665.                     RAISERROR (14053, 16, -1)
  12666.                     RETURN (1)
  12667.                 END
  12668.             /* If the subscription is enable for Sync Manager, then update the reg value */
  12669.             exec sp_MSsubscription_enabled_for_syncmgr
  12670.                 @publisher, @publisher_db, @publication, @subscriber, @subscriber_db, 
  12671.                 @enabled_for_syncmgr OUT, @regkey OUT
  12672.             IF @@ERROR <> 0
  12673.                 BEGIN
  12674.                     RAISERROR (14053, 16, -1)
  12675.                     RETURN (1)
  12676.                 END
  12677.             if @enabled_for_syncmgr = 1
  12678.                 begin
  12679.                     select @use_interactive_int = convert(int, @use_interactive_bit)
  12680.                     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  12681.                                            @regkey,
  12682.                                            'UseInteractiveResolver',
  12683.                                            'REG_DWORD',
  12684.                                             @use_interactive_int
  12685.                     if @retcode <> 0 OR @@ERROR <> 0
  12686.                         BEGIN
  12687.                             RAISERROR (14053, 16, -1)
  12688.                             RETURN (1)
  12689.                         END
  12690.                 end
  12691.  
  12692.         END
  12693.         
  12694.  
  12695.      
  12696.     IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = 'priority'
  12697.     BEGIN
  12698.  
  12699.         select @db_name = db_name from sysmergesubscriptions
  12700.             where (pubid=@pubid) and (subid=@pubid)
  12701.         IF @db_name <> db_name()
  12702.             BEGIN
  12703.                 RAISERROR (20047, 16, -1)
  12704.                 RETURN (1)
  12705.             END
  12706.  
  12707.         /* Only the original publisher can change priority of a global subscriptions */
  12708.  
  12709.         IF @subscriber_type<>1  
  12710.             BEGIN
  12711.                 RAISERROR (20044, 16, -1)  /* Local subscriber does not have priority*/
  12712.                 RETURN (1)
  12713.             END
  12714.  
  12715.          
  12716.         BEGIN TRANSACTION
  12717.         save tran sp_changemergepullsubscription
  12718.             exec dbo.sp_MSchange_priority @subid,  @value
  12719.             select @snapshot_ready=snapshot_ready from sysmergepublications where pubid = @pubid
  12720.             /* Insert the sp_MSchange_priority schema change only if the publication's snapshot is ready */
  12721.             if (@snapshot_ready > 0)
  12722.             begin
  12723.                  select @schemaversion = schemaversion from sysmergeschemachange
  12724.                 if (@schemaversion is NULL)
  12725.                 set @schemaversion = 1
  12726.                 else
  12727.                     select @schemaversion = 1 + max(schemaversion) from sysmergeschemachange
  12728.                 set @schemaguid = newid()
  12729.                 set @artid = newid()
  12730.                 set @schematype = 8 /* change priority */
  12731.                 select @schematext = 'exec dbo.sp_MSchange_priority '+ '''' + convert(nchar(36),@subid) + '''' + ',' + '''' + @value + '''' 
  12732.                  exec dbo.sp_MSinsertschemachange @pubid, @artid, @schemaversion, @schemaguid, @schematype, @schematext
  12733.                 if @@ERROR <> 0 goto Rollback_tran
  12734.             end             
  12735.         COMMIT TRANSACTION
  12736.  
  12737.     END
  12738.     
  12739.     IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) IN 
  12740.                            ('publisher_login',
  12741.                             'publisher_password',
  12742.                             'publisher_security_mode',
  12743.                             'distributor',
  12744.                             'distributor_login',
  12745.                             'distributor_password',
  12746.                             'distributor_security_mode',
  12747.                             'ftp_address',
  12748.                             'ftp_port',
  12749.                             'ftp_login',
  12750.                             'ftp_password',
  12751.                             'alt_snapshot_folder',
  12752.                             'working_directory',
  12753.                             'use_ftp',
  12754.                             'offload_agent',
  12755.                             'offload_server',
  12756.                             'dynamic_snapshot_location')
  12757.     BEGIN
  12758.         EXEC @retcode = sp_change_subscription_properties @publisher = @publisher,
  12759.                                                           @publisher_db = @publisher_db,
  12760.                                                           @publication = @publication,
  12761.                                                           @property = @property,
  12762.                                                           @value = @value,
  12763.                                                           @publication_type = 2
  12764.         IF @retcode <> 0
  12765.             RETURN 1
  12766.     END
  12767.  
  12768.  
  12769.     /*
  12770.     ** Return succeed.
  12771.     */
  12772.  
  12773.     RAISERROR (14054, 10, -1)
  12774.     RETURN (0)
  12775. Rollback_tran:
  12776.     rollback tran sp_changemergepullsubscription
  12777.     commit tran
  12778.     return(1)
  12779. go
  12780.  
  12781. exec dbo.sp_MS_marksystemobject sp_changemergepullsubscription 
  12782. go
  12783.  
  12784. grant execute on dbo.sp_changemergepullsubscription to public
  12785. go
  12786.  
  12787.  
  12788. raiserror('Creating procedure sp_helpmergepullsubscription', 0,1)
  12789. GO
  12790.  
  12791. CREATE PROCEDURE sp_helpmergepullsubscription(
  12792.     @publication         sysname = '%',        /* Publication name */
  12793.     @publisher            sysname = '%',      /* Publisher server */
  12794.     @publisher_db        sysname = '%',      /* Publication database */
  12795.     @subscription_type    nvarchar(10) = 'pull'    /* Show only pull subscriptions */
  12796.     )AS
  12797.     
  12798.     SET NOCOUNT ON
  12799.  
  12800.     /*
  12801.     ** Declarations.
  12802.     */
  12803.  
  12804.     declare @retcode             int
  12805.     declare @srvid                 int
  12806.     declare    @pubid                 uniqueidentifier
  12807.     declare    @subid                 uniqueidentifier
  12808.     declare    @partnerid             uniqueidentifier
  12809.     declare @cursor_open        int
  12810.     declare @subscriber            sysname
  12811.     declare @subscriber_db        sysname
  12812.     declare @subscription_set     nvarchar(10)
  12813.     declare @publisher_local    sysname
  12814.     declare @publisher_db_local    sysname
  12815.     declare @publication_local    sysname
  12816.     declare @subscription_name     nvarchar(1000)
  12817.     declare @regkey                nvarchar(1000)
  12818.     declare @syncmgr_keyexist                int
  12819.     declare @helpsubscriptioncursor_open    int
  12820.     
  12821.  
  12822.     /*
  12823.     ** Initializations.
  12824.     */
  12825.     set @cursor_open             = 0                    
  12826.  
  12827.     select @publisher_db = RTRIM(@publisher_db)
  12828.     select @publication = RTRIM(@publication)
  12829.     
  12830.     -- For attach
  12831.     if exists (select * from sysobjects where name = 'MSrepl_restore_stage')
  12832.         -- The database is attached from a subscription copy file without using
  12833.         -- sp_attachsubscription. Return nothing
  12834.         return 0
  12835.  
  12836.     /*
  12837.     **    Calling sp_help* is all right whether current database is enabled for pub/sub or not
  12838.     */
  12839.  
  12840.     IF not exists (select * from sysobjects where name='sysmergesubscriptions')
  12841.         RETURN (0)
  12842.  
  12843.     /* Security check */
  12844.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  12845.     if @@ERROR <> 0 or @retcode <> 0
  12846.         return(1)
  12847.  
  12848.     set @subscriber = @@SERVERNAME     
  12849.     set @subscriber_db = DB_NAME()
  12850.  
  12851.     /*
  12852.     ** Parameter Check: @publisher
  12853.     ** Check to make sure that the publisher is defined
  12854.     */
  12855.     IF @publisher <> '%' AND @publisher IS NOT NULL
  12856.     BEGIN
  12857.         EXECUTE @retcode = dbo.sp_validname @publisher
  12858.  
  12859.         IF @@ERROR <> 0 OR @retcode <> 0
  12860.                RETURN (1)
  12861.     END
  12862.  
  12863.     /*
  12864.     ** Parameter Check:  @publication.
  12865.     ** If the publication name is specified, check to make sure that it
  12866.     ** conforms to the rules for identifiers and that the publication
  12867.     ** actually exists.  Disallow NULL.
  12868.     */
  12869.     if @publication IS NULL
  12870.         BEGIN
  12871.             RAISERROR (14043, 16, -1, '@publication')
  12872.             RETURN (1)
  12873.         END
  12874.  
  12875.     /*
  12876.     ** Parameter Check: @subscription_type.
  12877.     ** Set subscription_typeid based on the @subscription_type specified.
  12878.     **
  12879.     **   subscription_type    subscription_type
  12880.     **   =================    ===============
  12881.     **             0             push
  12882.     **             1             pull
  12883.     **              0,1            both
  12884.     */
  12885.     if LOWER(@subscription_type collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('push', 'pull', 'both')
  12886.         BEGIN
  12887.               RAISERROR (14128, 16, -1)
  12888.             RETURN (1)
  12889.         END
  12890.     IF LOWER(@subscription_type collate SQL_Latin1_General_CP1_CS_AS) = 'both'
  12891.         set @subscription_set = '(0, 1)'
  12892.     else IF LOWER(@subscription_type collate SQL_Latin1_General_CP1_CS_AS) = 'push'
  12893.         set @subscription_set = '(0)'
  12894.     else 
  12895.         set @subscription_set = '(1,2)'   -- including pull subscription and pull/anonymous subscription
  12896.  
  12897.     IF NOT EXISTS (SELECT * FROM sysobjects WHERE 
  12898.         type = 'U' AND
  12899.         name = 'MSsubscription_properties')
  12900.         RETURN (0)
  12901.  
  12902.     /*
  12903.     ** Get subscriptions
  12904.     */
  12905.     
  12906.     create table #helpmergepullsubscription
  12907.                 (
  12908.                     publication                sysname        collate database_default not null,
  12909.                     publisher                sysname        collate database_default not null,
  12910.                     publisher_db            sysname        collate database_default not null,
  12911.                     subscriber                sysname        collate database_default not null,
  12912.                     subscriber_db             sysname        collate database_default not null,
  12913.                     status                    int         NOT NULL,
  12914.                     subscriber_type         int            NOT NULL,
  12915.                     subscription_type         int            NOT NULL,
  12916.                     priority                float(8)    NOT NULL,
  12917.                     sync_type                tinyint        NOT NULL,
  12918.                     description                nvarchar(255)     collate database_default null,
  12919.                     merge_jobid                binary(16)        NULL,
  12920.                     enabled_for_syncmgr        int                NULL,
  12921.                     last_updated            nvarchar(26)     collate database_default null,
  12922.                     use_interactive_resolver     int            NULL,
  12923.                     subid                    uniqueidentifier    not NULL,
  12924.                     last_sync_status        int                NULL,
  12925.                     last_sync_summary        sysname            collate database_default null
  12926.                 )
  12927.  
  12928.     IF @publisher IS NULL and @publisher_db IS NULL
  12929.         BEGIN
  12930.             select @subid = subid from sysmergesubscriptions where subid = partnerid
  12931.             set @partnerid = @subid
  12932.             -- show the loopback subscription
  12933.             insert into #helpmergepullsubscription 
  12934.                 select pubs.name, servers2.srvname, subs2.db_name, servers1.srvname, subs1.db_name, 
  12935.                     subs1.status, subs1.subscriber_type, subs1.subscription_type, subs1.priority, 
  12936.                     subs1.sync_type, subs1.description, replinfo.merge_jobid, 0, 
  12937.                     convert(nvarchar(12), subs1.last_sync_date, 112) + substring(convert(nvarchar(24), subs1.last_sync_date, 121), 11,13), 
  12938.                     subs1.use_interactive_resolver, @subid, subs1.last_sync_status, subs1.last_sync_summary
  12939.                 FROM      sysmergesubscriptions     subs1,
  12940.                           sysmergesubscriptions     subs2,
  12941.                           MSmerge_replinfo         replinfo,
  12942.                         master.dbo.sysservers     servers1,
  12943.                         master.dbo.sysservers     servers2,
  12944.                         sysmergepublications     pubs
  12945.                 where subs1.subid = @subid
  12946.                     and subs2.subid = @partnerid
  12947.                     and pubs.pubid = subs1.pubid
  12948.                     and servers1.srvid = subs1.srvid
  12949.                     and servers2.srvid = subs2.srvid
  12950.                     and subs1.subid = subs1.partnerid 
  12951.                     and replinfo.repid = subs1.subid 
  12952.             
  12953.         END
  12954.     else
  12955.         begin
  12956.             declare #cursor cursor local FAST_FORWARD FOR select DISTINCT sub.subid, sub.partnerid 
  12957.                 FROM sysmergesubscriptions     sub,
  12958.                 sysmergesubscriptions         sub1, 
  12959.                 master.dbo.sysservers        ss,  
  12960.                 master.dbo.sysservers        ss1, 
  12961.                 sysmergepublications         pub 
  12962.                  WHERE ((@subscriber = N'%') OR (UPPER(ss.srvname) = UPPER(@subscriber) collate database_default)) 
  12963.                     AND ((@publisher = N'%') OR (UPPER(ss1.srvname) = UPPER(@publisher) collate database_default)) 
  12964.                     AND sub1.srvid = ss1.srvid 
  12965.                        AND sub.srvid = ss.srvid  
  12966.                        AND pub.name LIKE  @publication  
  12967.                        AND sub.pubid = pub.pubid 
  12968.                                 AND ((@subscriber_db = N'%') OR (sub.db_name = @subscriber_db collate database_default))
  12969.                                 AND ((@publisher_db = N'%') OR (sub1.db_name = @publisher_db collate database_default))
  12970.                     AND sub1.pubid = pub.pubid 
  12971.                     AND (sub.subscription_type=1 or sub.subscription_type=2) 
  12972.                 FOR READ ONLY
  12973.  
  12974.             open #cursor
  12975.             select @cursor_open = 1                    
  12976.             fetch next from #cursor into @subid, @partnerid
  12977.             while (@@fetch_status <> -1)
  12978.                 begin
  12979.                     insert into #helpmergepullsubscription 
  12980.                         select pubs.name, servers2.srvname, subs2.db_name, servers1.srvname, subs1.db_name, 
  12981.                             subs1.status, subs1.subscriber_type, subs1.subscription_type, subs1.priority, 
  12982.                             subs1.sync_type, subs1.description, replinfo.merge_jobid, 0, 
  12983.                             convert(nvarchar(12), subs1.last_sync_date, 112) + substring(convert(nvarchar(24), subs1.last_sync_date, 121), 11,13), 
  12984.                             subs1.use_interactive_resolver, @subid, subs1.last_sync_status, subs1.last_sync_summary
  12985.                         FROM      sysmergesubscriptions     subs1,
  12986.                                   sysmergesubscriptions     subs2,
  12987.                                   MSmerge_replinfo         replinfo,
  12988.                                 master.dbo.sysservers    servers1,
  12989.                                 master.dbo.sysservers    servers2,
  12990.                                 sysmergepublications     pubs
  12991.                         where subs1.subid = @subid
  12992.                             and subs2.subid = @partnerid
  12993.                             and pubs.pubid = subs1.pubid
  12994.                             and servers1.srvid = subs1.srvid
  12995.                             and servers2.srvid = subs2.srvid
  12996.                             and @subid <> @partnerid -- do not show the loopback subscription
  12997.                             and replinfo.repid = subs1.subid 
  12998.         
  12999.                     if @@ERROR <> 0
  13000.                         begin
  13001.                             set @retcode = 1
  13002.                             goto DONE
  13003.                         end                    
  13004.                 fetch next from #cursor into @subid, @partnerid
  13005.             end
  13006.         end
  13007.         declare #helpsubscriptioncursor CURSOR LOCAL FAST_FORWARD FOR 
  13008.             select DISTINCT publisher, publisher_db, publication
  13009.                    FROM #helpmergepullsubscription
  13010.                 FOR READ ONLY
  13011.         create table #syncmgr_keyexist (syncmgr_keyexist int)
  13012.         open #helpsubscriptioncursor
  13013.         select @helpsubscriptioncursor_open = 1                    
  13014.         fetch next from #helpsubscriptioncursor into @publisher_local, @publisher_db_local, @publication_local
  13015.         while (@@fetch_status <> -1)
  13016.         begin
  13017.             set @subscription_name = @publisher_local + ':' + @publisher_db_local + ':' + @publication_local + ':' + @subscriber + ':' + @subscriber_db
  13018.             /* Replace back slash with forward slash so that the key name is a valid REGISTRY key name */
  13019.             set @subscription_name = REPLACE(@subscription_name,'\','/')
  13020.             set @regkey = 'SOFTWARE\Microsoft\Microsoft SQL Server\80\Replication\Subscriptions\' + @subscription_name
  13021.             insert into #syncmgr_keyexist EXECUTE master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', @regkey
  13022.             select @syncmgr_keyexist = syncmgr_keyexist from #syncmgr_keyexist
  13023.             update #helpmergepullsubscription set enabled_for_syncmgr = @syncmgr_keyexist 
  13024.                 where UPPER(publisher) = UPPER(@publisher_local)
  13025.                     and publisher_db = @publisher_db_local
  13026.                     and publication = @publication_local
  13027.             fetch next from #helpsubscriptioncursor into @publisher_local, @publisher_db_local, @publication_local
  13028.         end
  13029.  
  13030.     select 'subscription_name'= hs.publisher + ':' + hs.publisher_db + ':' + hs.publication collate database_default, hs.publication, hs.publisher,
  13031.             hs.publisher_db, hs.subscriber, hs.subscriber_db, hs.status, hs.subscriber_type, hs.subscription_type,
  13032.             hs.priority, hs.sync_type, hs.description, hs.merge_jobid, hs.enabled_for_syncmgr, hs.last_updated, sp.publisher_login,
  13033.             sp.publisher_password, sp.publisher_security_mode, sp.distributor, sp.distributor_login, 
  13034.             sp.distributor_password, sp.distributor_security_mode, 'ftp_address' = null, 'ftp_port' = 0, 
  13035.             'ftp_login' = null, 'ftp_password' = null, sp.alt_snapshot_folder, sp.working_directory, sp.use_ftp, 
  13036.             sp.offload_agent, sp.offload_server, hs.use_interactive_resolver, hs.subid, 
  13037.             sp.dynamic_snapshot_location, hs.last_sync_status, hs.last_sync_summary
  13038.                 from #helpmergepullsubscription hs
  13039.      left outer join MSsubscription_properties sp
  13040.                   on hs.publisher = sp.publisher collate database_default
  13041.                  and hs.publisher_db = sp.publisher_db collate database_default
  13042.                  and hs.publication = sp.publication collate database_default
  13043.             order by hs.publisher, hs.publisher_db, hs.publication, hs.subscriber, hs.subscriber_db
  13044.          
  13045.     select @retcode = 0
  13046. DONE:
  13047.     if (@cursor_open = 1)
  13048.         begin
  13049.             close #cursor
  13050.             deallocate #cursor
  13051.         end            
  13052.     --drop table #helpmergepullsubscription
  13053.  
  13054.     return @retcode    
  13055. go
  13056. exec dbo.sp_MS_marksystemobject sp_helpmergepullsubscription
  13057. go
  13058.  
  13059. grant execute on dbo.sp_helpmergepullsubscription to public
  13060. go
  13061.  
  13062. raiserror('Creating procedure sp_addmergepullsubscription_agent', 0,1)
  13063. GO
  13064. CREATE PROCEDURE sp_addmergepullsubscription_agent (
  13065.     @name                            sysname = NULL,
  13066.     @publisher                        sysname,                          /* Publisher server */
  13067.     @publisher_db                    sysname,                          /* Publisher database */
  13068.     @publication                     sysname,                          /* Publication name */
  13069.     @publisher_security_mode        int = 1,
  13070.     @publisher_login                sysname = NULL,
  13071.     @publisher_password                sysname = NULL,
  13072.     @publisher_encrypted_password    bit = 0,
  13073.     @subscriber                        sysname = NULL,
  13074.     @subscriber_db                    sysname = NULL,
  13075.     @subscriber_security_mode        int = NULL,                        /* 0 standard; 1 integrated */
  13076.     @subscriber_login                sysname = NULL,
  13077.     @subscriber_password            sysname = NULL,
  13078.     @distributor                    sysname = @@SERVERNAME,
  13079.     @distributor_security_mode        int = 0,                        /* 0 standard; 1 integrated */
  13080.     @distributor_login                sysname = 'sa',
  13081.     @distributor_password            sysname = NULL,
  13082.     @encrypted_password                bit = 0,            /* distributor password encrypted or not */
  13083.     @frequency_type                  int = NULL,
  13084.     @frequency_interval             int = NULL,                
  13085.     @frequency_relative_interval     int = NULL, 
  13086.     @frequency_recurrence_factor     int = NULL, 
  13087.     @frequency_subday                 int = NULL,
  13088.     @frequency_subday_interval         int = NULL,       
  13089.     @active_start_time_of_day         int = NULL, 
  13090.     @active_end_time_of_day         int = NULL,         
  13091.     @active_start_date                 int = NULL, 
  13092.     @active_end_date                 int = NULL,
  13093.     @optional_command_line             nvarchar(255) = '',            /* Optional command line arguments */
  13094.     @merge_jobid                    binary(16) = NULL OUTPUT,
  13095.     @enabled_for_syncmgr             nvarchar(5) = 'false', /* Enabled for SYNCMGR: true or false */
  13096.     @ftp_address                     sysname = NULL,
  13097.     @ftp_port                         int = NULL,
  13098.     @ftp_login                         sysname = NULL,
  13099.     @ftp_password                     sysname = NULL,
  13100.     @alt_snapshot_folder              nvarchar(255) = NULL,
  13101.     @working_directory                nvarchar(255) = NULL,
  13102.     @use_ftp                          nvarchar(5) = 'false',
  13103.     @reserved                         nvarchar(100) = N'', -- Not default to null because null problems in conditional expressions.
  13104.     @use_interactive_resolver       nvarchar(5) = 'false',
  13105.     @offloadagent                     nvarchar(5) = 'false',
  13106.     @offloadserver                    sysname = null,
  13107.     -- Used by DMO scripting
  13108.     @job_name                        sysname = NULL,
  13109.     @dynamic_snapshot_location      nvarchar(260) = NULL
  13110.     ) AS
  13111.  
  13112.     SET NOCOUNT ON
  13113.  
  13114.     /*
  13115.     ** Declarations.
  13116.     */
  13117.     declare @command                 nvarchar(4000)
  13118.     declare @retcode                 int
  13119.     declare @database                sysname
  13120.     declare @repid                    uniqueidentifier
  13121.     declare @pubid                    uniqueidentifier
  13122.     declare @subscriber_srvid        int 
  13123.     declare @publisher_srvid        int 
  13124.     declare @name_id                nvarchar(50)
  13125.     declare @subscriber_typeid        int
  13126.     declare @subscription_type_id    int
  13127.     declare @category_name            sysname
  13128.     declare @platform_nt            binary
  13129.     DECLARE @subscriber_enc_password     nvarchar(524)
  13130.     DECLARE @publisher_enc_password     nvarchar(524)
  13131.     DECLARE @distributor_enc_password     nvarchar(524)
  13132.     DECLARE @use_ftp_bit                bit
  13133.     declare @use_interactive_bit        bit
  13134.     DECLARE @offload_agent_bit          bit
  13135.  
  13136.     select @platform_nt = 0x1
  13137.  
  13138.     SELECT @use_ftp_bit = 0
  13139.  
  13140.     /* Security check */
  13141.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  13142.     if @@ERROR <> 0 or @retcode <> 0
  13143.         return(1)
  13144.         
  13145.     -- For attach check
  13146.     if exists (select * from sysobjects where name = 'MSrepl_restore_stage')
  13147.     begin
  13148.         raiserror(21211, 16, -1)
  13149.         return 1
  13150.     end
  13151.  
  13152.     -- Set null @optional_command_line to empty string to avoid string concat problem
  13153.     if @optional_command_line is null
  13154.         set @optional_command_line = ''
  13155.         else
  13156.                 set @optional_command_line = N' ' + LTRIM( RTRIM(@optional_command_line) ) + N' '
  13157.  
  13158.     IF @distributor_password = N''
  13159.         select @distributor_password = NULL
  13160.  
  13161.     IF @publisher_password = N''
  13162.         select @publisher_password = NULL
  13163.  
  13164.     IF @ftp_password = N''
  13165.         select @ftp_password = NULL
  13166.  
  13167.     /*
  13168.     ** Parameter Check: @subscriber and @subscriber_db
  13169.     */
  13170.  
  13171.     if @subscriber IS NULL or rtrim(@subscriber) = ''
  13172.         SELECT @subscriber = @@SERVERNAME
  13173.  
  13174.     if @subscriber_db IS NULL or rtrim(@subscriber_db) = ''
  13175.         SELECT @subscriber_db = DB_NAME()
  13176.     
  13177.     EXECUTE @retcode = dbo.sp_validname @subscriber
  13178.     IF @@ERROR <> 0 OR @retcode <> 0
  13179.        RETURN (1)
  13180.     
  13181.     EXECUTE @retcode = dbo.sp_validname @subscriber_db
  13182.     IF @@ERROR <> 0 OR @retcode <> 0
  13183.        RETURN (1)
  13184.  
  13185.     -- Parameter check: @subscriber_security_mode    
  13186.     if @subscriber_security_mode is null
  13187.     begin
  13188.         if ( platform() & @platform_nt ) = @platform_nt
  13189.             select @subscriber_security_mode = 1
  13190.         else
  13191.             select @subscriber_security_mode = 0
  13192.     end    
  13193.  
  13194.     /* 
  13195.     ** Parameter check: @alt_snapshot_folder 
  13196.     ** @alt_snapshot_folder and @use_ftp are mutually exclusive    
  13197.     ** @dynamic_snapshot_location is incompatible with both 
  13198.     ** @alt_snapshot_folder and @use_ftp
  13199.     */
  13200.  
  13201.     IF @alt_snapshot_folder <> N'' AND @alt_snapshot_folder IS NOT NULL
  13202.     BEGIN
  13203.         IF LOWER(@use_ftp collate SQL_Latin1_General_CP1_CS_AS) = N'true'
  13204.         BEGIN
  13205.             RAISERROR(21146, 16, -1)
  13206.             RETURN (1)
  13207.         END
  13208.         IF @dynamic_snapshot_location <> N'' AND @dynamic_snapshot_location IS NOT NULL
  13209.         BEGIN
  13210.             RAISERROR(21341, 16, -1)
  13211.             RETURN (1)
  13212.         END
  13213.     END
  13214.  
  13215.        /*
  13216.     ** Parameter Check: @use_interactive_resolver  
  13217.     */
  13218.     if LOWER(@use_interactive_resolver collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('true', 'false')
  13219.         BEGIN
  13220.             RAISERROR (14148, 16, -1, '@use_interactive_resolver')
  13221.             RETURN (1)
  13222.         END
  13223.     if LOWER(@use_interactive_resolver collate SQL_Latin1_General_CP1_CS_AS) = 'true'
  13224.         set @use_interactive_bit = 1
  13225.     else 
  13226.         set @use_interactive_bit = 0
  13227.  
  13228.     /* 
  13229.     ** Parameter check: @use_ftp
  13230.     ** Must be 'true' or 'false'
  13231.     */
  13232.     IF LOWER(@use_ftp collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('true', 'false')
  13233.     BEGIN
  13234.         RAISERROR (14148, 16, -1, '@use_ftp')
  13235.         RETURN (1)
  13236.     END
  13237.     
  13238.     IF LOWER(@use_ftp collate SQL_Latin1_General_CP1_CS_AS) = 'true'
  13239.     BEGIN
  13240.         /*
  13241.         ** Ftp file transfer is incompatible with @dynamic_snapshot_location
  13242.         */
  13243.         IF @dynamic_snapshot_location <> N'' AND @dynamic_snapshot_location IS NOT NULL
  13244.         BEGIN
  13245.             RAISERROR (21342, 16, -1)
  13246.             RETURN (1)
  13247.         END
  13248.  
  13249.         SELECT @use_ftp_bit = 1
  13250.  
  13251.     END
  13252.     ELSE
  13253.     BEGIN
  13254.         SELECT @use_ftp_bit = 0
  13255.     END
  13256.  
  13257.     /*
  13258.     ** Parameter Check: @offloadserver
  13259.     ** If @offloadagent = 'true' then @offloadserver cannot be null
  13260.     */
  13261.     SELECT @offloadagent = LOWER(@offloadagent collate SQL_Latin1_General_CP1_CS_AS)
  13262.     IF @offloadagent NOT IN ('true', 'false')
  13263.     BEGIN
  13264.         RAISERROR (14148, 16, -1, '@offloadagent')
  13265.         RETURN (1)
  13266.     END
  13267.  
  13268.     IF @offloadagent = 'true'
  13269.     BEGIN
  13270.         SELECT @offload_agent_bit = 1
  13271.     END
  13272.     ELSE
  13273.     BEGIN
  13274.         SELECT @offload_agent_bit = 0
  13275.     END
  13276.  
  13277.     IF @offload_agent_bit = 1 AND (@offloadserver IS NULL or
  13278.                                @offloadserver = N'')
  13279.     BEGIN
  13280.         RAISERROR(21215, 16, -1)
  13281.         RETURN (1)
  13282.     END
  13283.  
  13284.     IF UPPER(@offloadserver) = UPPER(@@SERVERNAME) AND
  13285.        @offload_agent_bit = 1
  13286.     BEGIN
  13287.         RAISERROR(21227, 16, -1)
  13288.         RETURN (1)
  13289.     END
  13290.  
  13291.     EXEC @retcode = sp_MSreplcheckoffloadserver @offloadserver
  13292.     IF @retcode <> 0 OR @@ERROR <> 0
  13293.         RETURN (1)
  13294.  
  13295.     -- Make sure that there are no leading or trailing blanks
  13296.     -- in the dynamic snapshot location
  13297.     select @dynamic_snapshot_location = rtrim(ltrim(@dynamic_snapshot_location))
  13298.  
  13299.     if ( ( platform() & @platform_nt ) <> @platform_nt and @subscriber_security_mode = 1)
  13300.     begin
  13301.         RAISERROR(21038, 16, -1)
  13302.         RETURN (1)
  13303.     end
  13304.  
  13305.     select @subscription_type_id = 1 /* pull agent only */
  13306.     /*
  13307.     ** Set Default schedule values if NULL is specified
  13308.     ** The default are not implemented during parmeter defintion because this procedure
  13309.     ** is can be called from sp_addmergesubscription.
  13310.     */
  13311.     if @frequency_type is NULL
  13312.         set @frequency_type = 4        /* Daily */
  13313.     if @frequency_interval is NULL
  13314.         set @frequency_interval = 1
  13315.     if @frequency_relative_interval is NULL
  13316.         set @frequency_relative_interval = 1
  13317.     if @frequency_recurrence_factor is NULL
  13318.         set @frequency_recurrence_factor = 0
  13319.     if @frequency_subday is NULL
  13320.         set @frequency_subday = 8    /* Hour */
  13321.     if @frequency_subday_interval is NULL
  13322.         set @frequency_subday_interval = 1
  13323.     if @active_start_time_of_day is NULL
  13324.         set @active_start_time_of_day = 0
  13325.     if @active_end_time_of_day is NULL
  13326.         set @active_end_time_of_day = 235959
  13327.     if @active_start_date is NULL
  13328.         set @active_start_date = 0
  13329.     if @active_end_date is NULL
  13330.         set @active_end_date = 99991231
  13331.  
  13332.     select @subscriber_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@@SERVERNAME) collate database_default
  13333.     IF @subscriber_srvid IS NULL
  13334.         BEGIN
  13335.            RAISERROR (14010, 16, -1)
  13336.            RETURN (1)     
  13337.         END
  13338.             
  13339.     select @pubid = pubid from sysmergepublications 
  13340.         where name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db
  13341.     IF @pubid is NULL
  13342.         begin
  13343.             RAISERROR (20026, 16, -1, @publication)
  13344.             RETURN (1)
  13345.         end
  13346.             
  13347.     select @repid = subid, @subscriber_typeid = subscriber_type from sysmergesubscriptions
  13348.             where srvid = @subscriber_srvid and pubid<>subid and pubid = @pubid and db_name = @subscriber_db
  13349.  
  13350.     if @subscriber_typeid = 3 set @subscription_type_id = 2 /* This corresponds to anonymous subscription */
  13351.  
  13352.     if (@subscription_type_id <> 0)
  13353.     begin
  13354.         if (@subscriber_security_mode = 0) and (@subscriber_login IS NULL or rtrim(@subscriber_login) = '')
  13355.         begin
  13356.             raiserror(3217, 16, -1, '@subscriber_login')
  13357.             return (1)
  13358.         end
  13359.     end
  13360.  
  13361.     if (@distributor_security_mode = 0) and (@distributor_login IS NULL or rtrim(@distributor_login) = '')
  13362.     begin
  13363.         raiserror(3217, 16, -1, '@distributor_login')
  13364.         return (1)
  13365.     end
  13366.  
  13367.     if (@publisher_security_mode = 0) and (@publisher_login IS NULL or rtrim(@publisher_login) = '')
  13368.     begin
  13369.         raiserror(3217, 16, -1, '@publisher_login')
  13370.         return (1)
  13371.     end
  13372.  
  13373.     IF NOT EXISTS (select * from sysobjects where name = 'MSsubscription_properties' and type = 'U')
  13374.     begin
  13375.         raiserror(14027, 16, -1, 'The subscription properties table ''MSsubscription_properties''')
  13376.         return (1)
  13377.     end
  13378.     
  13379.     declare @job_existing bit
  13380.     -- For scripting
  13381.     if @job_name is null
  13382.         select @job_existing = 0
  13383.     else
  13384.     begin
  13385.         select @job_existing = 1
  13386.         select @name = @job_name
  13387.     end
  13388.  
  13389.     /*
  13390.     ** Construct unique task name if @name = NULL
  13391.     */
  13392.     IF @name IS NULL
  13393.         begin
  13394.              SELECT @name = CONVERT(nvarchar(23),@publisher ) + '-' + CONVERT(nvarchar(23),@publisher_db) + '-' + 
  13395.                         CONVERT(nvarchar(23),@publication) + '-' + CONVERT(nvarchar(23),@subscriber) + '-' +
  13396.                         CONVERT(nvarchar(23), @subscriber_db) + '- 0'
  13397.         end
  13398.     else
  13399.     begin
  13400.         /*
  13401.         ** validate name
  13402.         */
  13403.         exec @retcode = dbo.sp_MSreplcheck_name @name
  13404.         if @@ERROR <> 0 or @retcode <> 0
  13405.             return(1)
  13406.  
  13407.     end
  13408.  
  13409.     -- Get property values.
  13410.     if @reserved = 'no_change_to_properties'
  13411.     begin
  13412.         -- Get the distributor value. It will be used in agent command line.
  13413.         select @distributor = distributor, 
  13414.             @enabled_for_syncmgr = case enabled_for_syncmgr
  13415.                 when 0 then 'false'
  13416.                 when 1 then    'true'
  13417.                 end
  13418.             from MSsubscription_properties where
  13419.             UPPER(publisher) = UPPER(@publisher)
  13420.             and publisher_db =  @publisher_db
  13421.             and publication = @publication
  13422.     end
  13423.  
  13424.     begin tran
  13425.     save tran sp_addpullsub_agent
  13426.  
  13427.     if @job_existing = 0
  13428.     begin
  13429.         /* Construct task command */
  13430.         select @command = '-Publisher ' + QUOTENAME(@publisher) + ' -PublisherDB ' + QUOTENAME(@publisher_db) + ' '
  13431.         select @command = @command + '-Publication ' + QUOTENAME(@publication) + ' '
  13432.         select @command = @command + '-Subscriber ' + QUOTENAME(@@SERVERNAME)  + ' '
  13433.         select @command = @command + '-SubscriberDB ' + QUOTENAME(db_name()) + ' '
  13434.         SELECT @command = @command + '-SubscriptionType ' + convert(nvarchar(10), @subscription_type_id)  + ' '
  13435.         
  13436.         select @command = @command + '-SubscriberSecurityMode ' + 
  13437.             convert(nvarchar(10),@subscriber_security_mode) + ' '
  13438.         if @subscriber_login is not NULL
  13439.             select @command = @command + '-SubscriberLogin ' + quotename(@subscriber_login) + ' '
  13440.         if @subscriber_password is not NULL
  13441.         begin
  13442.             set @subscriber_enc_password = @subscriber_password
  13443.             exec @retcode = master.dbo.xp_repl_encrypt @subscriber_enc_password OUTPUT
  13444.             select @command = @command + '-SubscriberEncryptedPassword ' + quotename(@subscriber_enc_password) + ' '
  13445.         end
  13446.         
  13447.         select @command = @command + @optional_command_line
  13448.         select @command = @command + ' -Distributor ' + QUOTENAME(@distributor) + ' '
  13449.  
  13450.         if @offload_agent_bit = 1
  13451.             select @command = @command + N'-Offload ' + @offloadserver + N' '
  13452.         
  13453.         select @dynamic_snapshot_location = rtrim(ltrim(@dynamic_snapshot_location))
  13454.         if @dynamic_snapshot_location is not null and 
  13455.            @dynamic_snapshot_location <> N''
  13456.             select @command = @command + N'-DynamicSnapshotLocation ' + fn_replquotename(@dynamic_snapshot_location) collate database_default + N' '
  13457.  
  13458.         select @database = db_name()
  13459.  
  13460.         -- Get Merge category name (assumes category_id = 14)
  13461.         select @category_name = name FROM msdb.dbo.syscategories where category_id = 14
  13462.  
  13463.         EXEC @retcode = dbo.sp_MSadd_repl_job
  13464.                 @name = @name,
  13465.                 @subsystem = 'Merge',
  13466.                 @server = @@SERVERNAME,
  13467.                 @databasename = @database,
  13468.                 @enabled = 1,
  13469.                 @freqtype = @frequency_type,
  13470.                 @freqinterval = @frequency_interval,
  13471.                 @freqsubtype = @frequency_subday,
  13472.                 @freqsubinterval = @frequency_subday_interval,
  13473.                 @freqrelativeinterval = @frequency_relative_interval,
  13474.                 @freqrecurrencefactor = @frequency_recurrence_factor,
  13475.                 @activestartdate = @active_start_date,
  13476.                 @activeenddate = @active_end_date,
  13477.                 @activestarttimeofday = @active_start_time_of_day,
  13478.                 @activeendtimeofday = @active_end_time_of_day,
  13479.                 @command = @command,
  13480.                 @retryattempts = 10,
  13481.                 @retrydelay = 1,
  13482.                 @category_name = @category_name,
  13483.                 @job_id = @merge_jobid OUTPUT
  13484.  
  13485.         if @@ERROR <> 0 or @retcode <> 0 goto Rollback_tran
  13486.     end
  13487.     else
  13488.     begin
  13489.         select @merge_jobid = job_id from msdb..sysjobs_view where 
  13490.             name = @name collate database_default and
  13491.             UPPER(originating_server) = UPPER(CONVERT(sysname, SERVERPROPERTY('ServerName')))
  13492.         if @merge_jobid IS NULL
  13493.         begin
  13494.             -- Message from msdb.dbo.sp_verify_job_identifiers
  13495.             RAISERROR(14262, -1, -1, 'Job', @name)          
  13496.             goto Rollback_tran
  13497.         end
  13498.     end
  13499.  
  13500.  
  13501.     if @reserved <> 'attach_subscription' and (@subscription_type_id = 1) OR (@subscription_type_id = 2)
  13502.     begin
  13503.         IF NOT EXISTS (select * from MSsubscription_properties 
  13504.             where UPPER(publisher) = UPPER(@publisher)
  13505.             and publisher_db =  @publisher_db
  13506.             and publication = @publication) 
  13507.         BEGIN
  13508.             
  13509.             -- Copy the passwords to new value before attempting to encrypt
  13510.             set @distributor_enc_password = @distributor_password
  13511.             set @publisher_enc_password = @publisher_password
  13512.  
  13513.             IF (@encrypted_password = 0)
  13514.             -- Encrypt the password
  13515.             BEGIN
  13516.                 EXEC @retcode = master.dbo.xp_repl_encrypt @distributor_enc_password OUTPUT
  13517.                 IF @@error <> 0 OR @retcode <> 0 goto Rollback_tran
  13518.             END
  13519.     
  13520.             IF (@publisher_encrypted_password = 0)
  13521.             -- Encrypt the password
  13522.             BEGIN
  13523.                 EXEC @retcode = master.dbo.xp_repl_encrypt @publisher_enc_password OUTPUT
  13524.                 IF @@error <> 0 OR @retcode <> 0 goto Rollback_tran
  13525.             END
  13526.     
  13527.             INSERT INTO MSsubscription_properties 
  13528.             (publisher, publisher_db, publication, publication_type, 
  13529.              publisher_login,publisher_password, publisher_security_mode, 
  13530.              distributor, distributor_login, distributor_password, 
  13531.              distributor_security_mode, ftp_address, ftp_port, ftp_login, 
  13532.              ftp_password, alt_snapshot_folder, working_directory, use_ftp,
  13533.              offload_agent, offload_server, dynamic_snapshot_location)
  13534.             values 
  13535.             (@publisher, @publisher_db, @publication, 2, @publisher_login, 
  13536.              @publisher_enc_password, @publisher_security_mode, @distributor, 
  13537.              @distributor_login, @distributor_enc_password, 
  13538.              @distributor_security_mode, null, null, null,
  13539.              null, @alt_snapshot_folder, @working_directory, @use_ftp_bit,
  13540.              @offload_agent_bit, @offloadserver, @dynamic_snapshot_location)
  13541.         END
  13542.     end
  13543.  
  13544.         
  13545.     /* Update merge joibd for this pull subscription */
  13546.     UPDATE MSmerge_replinfo set merge_jobid = @merge_jobid WHERE repid = @repid
  13547.  
  13548.     /* Update the distributor column in sysmergesubscriptions */
  13549.     UPDATE sysmergesubscriptions set 
  13550.             use_interactive_resolver = @use_interactive_bit,
  13551.             distributor = @distributor 
  13552.                 WHERE subid = @repid
  13553.     
  13554.     /* Conditional support for MobileSync */
  13555.     if LOWER(@enabled_for_syncmgr collate SQL_Latin1_General_CP1_CS_AS) = 'true'
  13556.     BEGIN
  13557.         /* Call sp_MSregistersubscription so that the subscription can be synchronized via MobileSync etc. */
  13558.         exec @retcode = dbo.sp_MSregistersubscription @replication_type = 2,
  13559.                                     @publisher = @publisher,
  13560.                                     @publisher_security_mode = @publisher_security_mode,
  13561.                                     @publisher_login = @publisher_login,
  13562.                                     @publisher_password = @publisher_password,
  13563.                                     @publisher_db = @publisher_db,
  13564.                                     @publication = @publication,
  13565.                                     @subscriber = @subscriber,
  13566.                                     @subscriber_db = @subscriber_db,
  13567.                                     @subscriber_security_mode = @subscriber_security_mode,
  13568.                                     @subscriber_login = @subscriber_login,
  13569.                                     @subscriber_password = @subscriber_password,
  13570.                                     @distributor = @distributor,
  13571.                                     @distributor_security_mode = @distributor_security_mode,
  13572.                                     @distributor_login = @distributor_login,
  13573.                                     @distributor_password = @distributor_password,
  13574.                                     @subscription_id = @repid,
  13575.                                     @subscription_type = @subscription_type_id,
  13576.                                     @use_interactive_resolver = @use_interactive_bit
  13577.  
  13578.         IF @@ERROR <> 0 or @retcode <> 0 goto Rollback_tran
  13579.     END
  13580.  
  13581. commit tran
  13582.     RETURN (0)
  13583. Rollback_tran:
  13584.     rollback tran sp_addpullsub_agent
  13585.     commit tran
  13586.     return(1)
  13587. GO
  13588.  
  13589. exec dbo.sp_MS_marksystemobject sp_addmergepullsubscription_agent
  13590. go
  13591.  
  13592. raiserror('Creating procedure sp_MSget_mergepullsubsagent_owner', 0,1)
  13593. GO
  13594. CREATE PROCEDURE sp_MSget_mergepullsubsagent_owner(
  13595.     @publication         sysname = NULL,                  /* Publication name */
  13596.     @publisher            sysname = NULL,              /* Publisher server */
  13597.     @publisher_db        sysname = NULL,              /* Publication database */
  13598.     @owner_sid          varbinary(85) OUTPUT
  13599.     )AS
  13600.     
  13601.     declare @srvid  int
  13602.     declare @pubid  uniqueidentifier 
  13603.     declare @subid  uniqueidentifier
  13604.     declare @job_id uniqueidentifier
  13605.     set nocount on
  13606.  
  13607.     select @owner_sid = NULL
  13608.  
  13609.     if exists (select * from sysobjects 
  13610.                where type = 'U' and
  13611.                      name = 'sysmergesubscriptions')
  13612.         -- Get the server id of the current server (subscriber)
  13613.     begin
  13614.         -- Get the srvid of the current subscriber database 
  13615.         select @srvid = srvid 
  13616.         from master.dbo.sysservers      
  13617.         where upper(@@servername) = upper(srvname) collate database_default
  13618.  
  13619.         -- Get the pubid from sysmergepublications using @publisher, 
  13620.         -- @publisher_db, @publication 
  13621.         select @pubid = pubid
  13622.         from sysmergepublications
  13623.         where @publication = name
  13624.  
  13625.         -- Get the subid from sysmergesubscriptions using @pubid and @srvid
  13626.         select @subid = subid
  13627.         from sysmergesubscriptions
  13628.         where @pubid = pubid and
  13629.               @srvid = srvid and
  13630.               pubid <> subid 
  13631.  
  13632.         -- Get the merge_jobid from MSreplication_info using @subid
  13633.         select @job_id = merge_jobid
  13634.         from MSmerge_replinfo
  13635.         where @subid = repid
  13636.  
  13637.         -- Finally, get the owner_sid from msdb..sysjobs using @job_id
  13638.         select @owner_sid = owner_sid
  13639.         from msdb..sysjobs 
  13640.         where @job_id = job_id
  13641.     end
  13642. go
  13643.  
  13644. exec dbo.sp_MS_marksystemobject 'sp_MSget_mergepullsubsagent_owner'
  13645.  
  13646. raiserror('Creating procedure sp_dropmergepullsubscription', 0,1)
  13647. GO
  13648. CREATE PROCEDURE sp_dropmergepullsubscription(
  13649.     @publication        sysname = NULL,             /* Publication name */
  13650.     @publisher          sysname = NULL,             /* Publisher server */
  13651.     @publisher_db       sysname = NULL,             /* Publication database */
  13652.     @reserved           bit = 0
  13653.     )AS
  13654.  
  13655.     SET NOCOUNT ON
  13656.  
  13657.     /*
  13658.     ** Declarations.
  13659.     */
  13660.  
  13661.     declare @retcode                int
  13662.     declare @subscriber_srvid       int
  13663.     declare @publisher_srvid        int
  13664.     declare @pubid                  uniqueidentifier
  13665.     declare @subid                  uniqueidentifier
  13666.     declare @partnerid              uniqueidentifier 
  13667.     declare @local_server           sysname
  13668.     declare @local_db               sysname
  13669.     declare @merge_jobid            binary(16)
  13670.     declare @cmd                    nvarchar(255)
  13671.     declare @pubidstr               nvarchar(38)
  13672.     declare @subscriber             sysname
  13673.     declare @subscriber_db          sysname
  13674.     declare @subscriber_type        int
  13675.     declare @local_job              bit
  13676.     declare @implicit_transaction   int
  13677.     declare @close_cursor_at_commit int
  13678.     declare @owner_sid              varbinary(85)
  13679.     declare @owner_name             sysname
  13680.     declare @qualified_publication_name nvarchar(512)
  13681.  
  13682.  
  13683.     select @close_cursor_at_commit = 0
  13684.     select @implicit_transaction = 0
  13685.  
  13686.     /*
  13687.     ** Get original setting values before setting them to false for recursive calling
  13688.     */
  13689.     IF (@reserved = 0)
  13690.     BEGIN
  13691.         SELECT @implicit_transaction = @@options & 2
  13692.         SELECT @close_cursor_at_commit = @@options & 4
  13693.         SET IMPLICIT_TRANSACTIONS OFF
  13694.         SET CURSOR_CLOSE_ON_COMMIT OFF
  13695.     END
  13696.  
  13697.     /* 
  13698.     ** Security Check.
  13699.     */
  13700.     exec @retcode = dbo.sp_MSreplcheck_subscribe
  13701.     if @@ERROR <> 0 or @retcode <> 0
  13702.         return(1)
  13703.  
  13704.      /*
  13705.     ** Initializations.
  13706.     */              
  13707.     set @local_db = DB_NAME()
  13708.     set @local_server = @@SERVERNAME
  13709.     set @subscriber = @@SERVERNAME   
  13710.     set @subscriber_db = DB_NAME()
  13711.  
  13712.    /*
  13713.     ** Assign parameter values appropriately
  13714.     */
  13715.             
  13716.     select @subscriber_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber) collate database_default
  13717.     IF @subscriber_srvid IS NULL
  13718.         BEGIN
  13719.            RAISERROR (14010, 16, -1)
  13720.            RETURN (1)     
  13721.         END
  13722.         
  13723.     IF not exists (select name from sysobjects where name='sysmergesubscriptions')
  13724.         BEGIN
  13725.             RAISERROR (14055, 16, -1)
  13726.             RETURN (1)
  13727.         END     
  13728.  
  13729.     /*
  13730.     ** Parameter Check: @publisher
  13731.     ** Check to make sure that the publisher is defined
  13732.     */
  13733.             IF @publisher IS NULL
  13734.             BEGIN
  13735.                 RAISERROR (14043, 16, -1, '@publisher')
  13736.                 RETURN (1)
  13737.             END
  13738.  
  13739.             EXECUTE @retcode = dbo.sp_validname @publisher
  13740.             IF @@ERROR <> 0 OR @retcode <> 0
  13741.                RETURN (1)
  13742.  
  13743.     /*
  13744.     ** Parameter Check: @publisher_db
  13745.     */
  13746.             IF @publisher_db IS NULL
  13747.             BEGIN
  13748.                 RAISERROR (14043, 16, -1, '@publisher_db')
  13749.                 RETURN (1)
  13750.             END    
  13751.  
  13752.     /*
  13753.     ** Parameter Check:  @publication.
  13754.     ** If the publication name is specified, check to make sure that it
  13755.     ** conforms to the rules for identifiers and that the publication
  13756.     ** actually exists.  Disallow NULL.
  13757.     */
  13758.     if @publication IS NULL
  13759.         BEGIN
  13760.             RAISERROR (14043, 16, -1, '@publication')
  13761.             RETURN (1)
  13762.         END
  13763.  
  13764.     IF LOWER(@publication) = 'all'
  13765.         BEGIN
  13766.             declare hC1 CURSOR LOCAL FAST_FORWARD FOR select DISTINCT name FROM sysmergepublications FOR READ ONLY
  13767.             
  13768.             OPEN hC1
  13769.             FETCH hC1 INTO @publication
  13770.             if @@fetch_status = -1 
  13771.                 begin
  13772.                     CLOSE hC1
  13773.                     DEALLOCATE hC1
  13774.                     RETURN (0) --- It's OK to have no publication when 'ALL'
  13775.                 end
  13776.             WHILE (@@fetch_status <> -1)
  13777.                 BEGIN
  13778.                     EXECUTE dbo.sp_dropmergepullsubscription @publication = @publication,
  13779.                                       @publisher = @publisher,
  13780.                                       @publisher_db = @publisher_db,
  13781.                                       @reserved = 1
  13782.                     FETCH hC1 INTO @publication
  13783.                 END
  13784.             CLOSE hC1
  13785.             DEALLOCATE hC1
  13786.             RETURN (0)
  13787.         END
  13788.         
  13789.     IF LOWER(@publisher) = 'all'
  13790.         BEGIN
  13791.             declare hC4 CURSOR LOCAL FAST_FORWARD FOR select DISTINCT srvname FROM master..sysservers FOR READ ONLY
  13792.             
  13793.             OPEN hC4
  13794.             FETCH hC4 INTO @publisher
  13795.             WHILE (@@fetch_status <> -1)
  13796.                 BEGIN
  13797.                     EXECUTE dbo.sp_dropmergepullsubscription @publication = @publication,
  13798.                                                 @publisher = @publisher,
  13799.                                                 @publisher_db = @publisher_db,
  13800.                                                 @reserved = 1
  13801.                     FETCH hC4 INTO @publisher
  13802.                 END
  13803.             CLOSE hC4
  13804.             DEALLOCATE hC4
  13805.             RETURN (0)
  13806.         END
  13807.  
  13808.     /*
  13809.     ** Validate that the publisher is a valid server
  13810.     */
  13811.     select @publisher_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher) collate database_default
  13812.     IF @publisher_srvid IS NULL
  13813.         BEGIN
  13814.             --RAISERROR (14010, 16, -1)
  13815.             RETURN (1)
  13816.         END
  13817.  
  13818.  
  13819.     /* Previously the condition is set as 'AND subid<>pubid' which is fatally errorous */
  13820.  
  13821.     IF LOWER(@publisher_db) = 'all'
  13822.         BEGIN
  13823.             declare hC5 CURSOR LOCAL FAST_FORWARD FOR select DISTINCT db_name FROM sysmergesubscriptions 
  13824.                     WHERE subid = pubid and pubid in (select pubid from sysmergepublications 
  13825.                             where UPPER(publisher)=UPPER(@publisher) 
  13826.                                 and name=@publication)
  13827.                                 
  13828.                         FOR READ ONLY
  13829.             
  13830.             OPEN hC5
  13831.             FETCH hC5 INTO @publisher_db
  13832.             WHILE (@@fetch_status <> -1)
  13833.                 BEGIN
  13834.                     EXECUTE dbo.sp_dropmergepullsubscription @publication = @publication,
  13835.                                       @publisher = @publisher,
  13836.                                       @publisher_db = @publisher_db,
  13837.                                       @reserved = 1
  13838.                     FETCH hC5 INTO @publisher_db
  13839.                 END
  13840.             CLOSE hC5
  13841.             DEALLOCATE hC5
  13842.             RETURN (0)
  13843.         END
  13844.  
  13845.     /*
  13846.     ** return error if only there is no 'ALL'. Same is true for the rest of error handling.
  13847.     */
  13848.     if NOT EXISTS (select * FROM sysmergepublications 
  13849.     WHERE name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db) 
  13850.     BEGIN
  13851.         if @reserved = 0
  13852.             RAISERROR (20026, 16, -1, @publication)
  13853.         RETURN (1)
  13854.     END
  13855.         
  13856.     select @pubid = pubid from sysmergepublications where name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db
  13857.     set @pubidstr = '''' + convert(nchar(36), @pubid) + ''''
  13858.     if @pubid is null  
  13859.         BEGIN
  13860.             if @reserved = 0
  13861.                 RAISERROR (20026, 16, -1, @publication)
  13862.             RETURN (1)
  13863.         END
  13864.  
  13865.     /*
  13866.     ** Only members of the sysadmin group and the creator of the distribution
  13867.     ** agent can drop a pull subscription successfully. This behavior matches 
  13868.     ** the behavior of the sysjobs_view. DBO of the subscriber database, 
  13869.     ** sysadmins (owner is undefined) can drop a subscription if the owner_sid 
  13870.     ** is null.
  13871.     */
  13872.     
  13873.     EXEC sp_MSget_mergepullsubsagent_owner @publisher = @publisher,
  13874.                                            @publisher_db = @publisher_db,
  13875.                                            @publication = @publication,
  13876.                                            @owner_sid = @owner_sid OUTPUT 
  13877.     
  13878.     IF (@owner_sid is not null AND
  13879.         (SUSER_SID() <> @owner_sid) AND
  13880.         (ISNULL(IS_SRVROLEMEMBER('sysadmin'),0) = 0))
  13881.     BEGIN
  13882.         SELECT @owner_name = SUSER_SNAME(@owner_sid)
  13883.         SELECT @qualified_publication_name = @publisher + N':' + 
  13884.                                              @publisher_db + N':' +
  13885.                                              @publication
  13886.         RAISERROR(21121,16,-1,@owner_name, @qualified_publication_name) 
  13887.         RETURN (1)
  13888.     END
  13889.  
  13890.     /*
  13891.     ** Get subscriptions from either local replicas or global replicas
  13892.     */
  13893.     select @subid = subs1.subid, @subscriber_type = subs1.subscriber_type, @partnerid = subs2.subid from
  13894.         sysmergesubscriptions   subs1,
  13895.         sysmergesubscriptions   subs2,
  13896.         sysmergepublications        pubs
  13897.         where subs1.srvid = @subscriber_srvid
  13898.             and subs1.db_name = @subscriber_db
  13899.             and subs2.srvid = @publisher_srvid
  13900.             and subs2.db_name = @publisher_db
  13901.             and subs1.pubid = subs2.subid
  13902.             and subs2.pubid = pubs.pubid
  13903.             and pubs.name = @publication
  13904.             and UPPER(pubs.publisher)=UPPER(@publisher)
  13905.             and pubs.publisher_db=@publisher_db
  13906.  
  13907.     if @subid IS NULL 
  13908.         begin
  13909.             if @reserved = 0 
  13910.                 raiserror (14050, 16, -1)
  13911.             RETURN (0)
  13912.         end                 
  13913.  
  13914.     begin tran
  13915.     save TRAN dropmergepullsubscription
  13916.     
  13917.         /*  
  13918.         ** Drop the local merge task
  13919.         */
  13920.         select @merge_jobid = merge_jobid from MSmerge_replinfo WHERE repid = @subid
  13921.         if (@merge_jobid IS NOT NULL)
  13922.         BEGIN
  13923.             IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @merge_jobid)
  13924.             BEGIN
  13925.  
  13926.                 -- Checks if the job name matches one that is generated
  13927.                 -- by replication
  13928.                 EXEC @retcode = dbo.sp_MSispullmergejobnamegenerated
  13929.                                     @publisher = @publisher,
  13930.                                     @publisher_db = @publisher_db,
  13931.                                     @publication = @publication,
  13932.                                     @job_id = @merge_jobid
  13933.                 IF @@ERROR <> 0
  13934.                     GOTO FAILURE
  13935.  
  13936.                 -- Only drop the job if the name was generated
  13937.                 IF @retcode = 0
  13938.                 BEGIN
  13939.                     EXEC @retcode = msdb.dbo.sp_delete_job @job_id = @merge_jobid
  13940.                     IF @@ERROR <> 0 or @retcode <> 0
  13941.                         GOTO FAILURE
  13942.                 END
  13943.             END
  13944.         END                                 
  13945.  
  13946.         if @subid <> @partnerid
  13947.         BEGIN
  13948.             DELETE MSmerge_replinfo WHERE repid = @subid 
  13949.             IF @@ERROR <> 0
  13950.                 GOTO FAILURE
  13951.             delete from sysmergesubscriptions where subid = @subid
  13952.             if @@ERROR <> 0
  13953.                 GOTO FAILURE
  13954.  
  13955.             /* Call sp_MSunregistersubscription so that the reg entries get deleted */
  13956.             exec @retcode = dbo.sp_MSunregistersubscription @publisher = @publisher,
  13957.                                         @publisher_db = @publisher_db,
  13958.                                         @publication = @publication,
  13959.                                         @subscriber = @@SERVERNAME,
  13960.                                         @subscriber_db = @subscriber_db
  13961.             IF @retcode<>0 or @@ERROR<>0
  13962.                 GOTO FAILURE
  13963.  
  13964.             exec dbo.sp_MSpublicationcleanup @publisher=@publisher, 
  13965.                                             @publisher_db = @publisher_db,
  13966.                                             @publication = @publication
  13967.             IF @@ERROR <> 0 
  13968.                 BEGIN
  13969.                     RAISERROR (20025, 16, -1, @publication)
  13970.                     GOTO FAILURE
  13971.                 END
  13972.         END
  13973.         
  13974.         IF EXISTS(select * from sysobjects where type='U' and name = 'MSsubscription_properties')
  13975.         BEGIN
  13976.             DELETE FROM MSsubscription_properties 
  13977.             WHERE UPPER(publisher) = UPPER(@publisher)  AND
  13978.             publisher_db  = @publisher_db AND
  13979.             publication = @publication 
  13980.     
  13981.             IF @@ERROR <> 0 
  13982.                 GOTO FAILURE
  13983.     
  13984.             IF NOT EXISTS (SELECT * FROM MSsubscription_properties)
  13985.             BEGIN
  13986.                 exec @retcode = dbo.sp_MSsub_cleanup_prop_table
  13987.                 IF @@ERROR <> 0 or @retcode <> 0
  13988.                     GOTO FAILURE
  13989.             END
  13990.         END
  13991.  
  13992.     COMMIT TRAN
  13993.  
  13994.     /*
  13995.     ** Set back original settings
  13996.     */
  13997.     IF @reserved = 0
  13998.     BEGIN
  13999.         /* 
  14000.         ** If last subscription is dropped and the DB is not enabled for publishing,
  14001.         ** then remove the merge system tables
  14002.         */
  14003.         IF (not exists (select * from sysmergesubscriptions )) 
  14004.             AND (select category & 4 FROM master..sysdatabases WHERE name = DB_NAME())=0
  14005.         BEGIN
  14006.                 execute @retcode = dbo.sp_MSdrop_mergesystables
  14007.                 if @@ERROR <> 0 or @retcode <> 0
  14008.                     begin
  14009.                         return (1)
  14010.                     end
  14011.         END 
  14012.  
  14013.         IF @implicit_transaction <>0 
  14014.             SET IMPLICIT_TRANSACTIONS ON
  14015.         IF @close_cursor_at_commit <>0 
  14016.             SET CURSOR_CLOSE_ON_COMMIT ON
  14017.     END
  14018.  
  14019.     RETURN(0)       
  14020.  
  14021. FAILURE:
  14022.     RAISERROR (14056, 16, -1)
  14023.     if @@trancount > 0
  14024.     begin
  14025.         ROLLBACK TRANSACTION dropmergepullsubscription
  14026.         COMMIT TRANSACTION
  14027.     end
  14028.     /*
  14029.     ** Set back original settings
  14030.     */  
  14031.     IF @reserved = 0
  14032.     BEGIN
  14033.         IF @implicit_transaction <>0 
  14034.             SET IMPLICIT_TRANSACTIONS ON
  14035.         IF @close_cursor_at_commit <>0 
  14036.             SET CURSOR_CLOSE_ON_COMMIT ON
  14037.     END
  14038.     return 1
  14039. go
  14040. exec dbo.sp_MS_marksystemobject sp_dropmergepullsubscription
  14041. go
  14042.  
  14043. grant execute on dbo.sp_dropmergepullsubscription to public
  14044. go
  14045.  
  14046. -- synctran supporting sprocs
  14047. raiserror('Creating procedure sp_MSreplraiserror', 0,1)
  14048. go
  14049.  
  14050. create proc sp_MSreplraiserror @errorid int, @param1 sysname = null, @param2 sysname= null
  14051. as
  14052.     if @errorid = 20508 raiserror (20508, 16, 1)
  14053.     else if @errorid = 20509 raiserror (20509, 16, 1)
  14054.     else if @errorid = 20510 raiserror (20510, 16, 1)
  14055.     else if @errorid = 20511 raiserror (20511, 16, 1)
  14056.     else if @errorid = 20512 raiserror (20512, 16, 1)
  14057.     else if @errorid = 20515 raiserror (20515, 16, 1)
  14058.     else if @errorid = 20516 raiserror (20516, 16, 1)
  14059.     else if @errorid = 20517 raiserror (20517, 16, 1)
  14060.     else if @errorid = 20518 raiserror (20518, 16, 1)
  14061.     else if @errorid = 20519 raiserror (20519, 16, 1)
  14062.     else if @errorid = 20520 raiserror (20520, 16, 1)
  14063.     else if @errorid = 21034 raiserror (21034, 16, 1)
  14064.     else if @errorid = 21052 raiserror (21052, 16, 1)
  14065.     else if @errorid = 21054 raiserror (21054, 16, 1)
  14066.     else if @errorid = 21064 raiserror (21064, 16, 1)
  14067.     else if @errorid = 21161 raiserror (21161, 16, 1)
  14068.     else if @errorid = 20598 raiserror (20598, 16, 1)
  14069. go
  14070. exec dbo.sp_MS_marksystemobject sp_MSreplraiserror
  14071. go
  14072.  
  14073. --
  14074. -- Name: sp_check_sync_trigger
  14075. --
  14076. -- Description: This SP is used by insert sync trigger on subscriber to check the trigger nesting level. 
  14077. -- The SP returns 1 if the trigger nestlevel is > 0. Else it returns 0.
  14078. --
  14079. -- Parameter: Refer to the comments in the create procedure statement
  14080. --
  14081. -- Returns: 1 = there is a nesting in the synctran trigger, 0 = no nesting
  14082. --  -1 = Error
  14083. --
  14084. -- Security: Public procedure - Internal security check. 
  14085. --
  14086. raiserror('Creating procedure sp_check_sync_trigger', 0,1)
  14087. go
  14088. create proc sp_check_sync_trigger
  14089. (
  14090.     @trigger_procid int
  14091.     ,@trigger_op char(10) OUTPUT
  14092.     ,@owner sysname = null
  14093. )
  14094. as
  14095. begin
  14096.     declare @trigid int
  14097.     --
  14098.     -- Security check
  14099.     -- Make sure this proc is infact being called from the given object(trigger)
  14100.     -- 
  14101.     if (trigger_nestlevel(@trigger_procid) = 0)
  14102.     begin
  14103.         raiserror(14126, 16, 2)
  14104.         return -1
  14105.     end
  14106.     --
  14107.     -- Security check: the caller of this SP has to be one of the 
  14108.     -- predefined replication triggers defined in the db
  14109.     --
  14110.     if (@owner is null)
  14111.     begin
  14112.         if (@trigger_procid not in (select object_id(object_name) 
  14113.                 from dbo.MSreplication_objects
  14114.                 where object_type = 'T'))
  14115.         begin
  14116.             raiserror(14126, 16, 3)
  14117.             return -1
  14118.         end
  14119.     end
  14120.     else
  14121.     begin
  14122.         if (@trigger_procid not in (select object_id(quotename(@owner) + N'.' + quotename(object_name)) 
  14123.                 from dbo.MSreplication_objects
  14124.                 where object_type = 'T'))
  14125.         begin
  14126.             raiserror(14126, 16, 3)
  14127.             return -1
  14128.         end
  14129.     end
  14130.     --
  14131.     -- process
  14132.     --
  14133.     select @trigger_op = NULL
  14134.     select @trigid = so1.id from sysobjects so1, sysobjects so2 where
  14135.     so1.type = N'TR' and so1.name like N'trg_MSsync_ins_%' and so1.parent_obj = so2.parent_obj
  14136.     and so2.id = @trigger_procid
  14137.     
  14138.     -- if nestlevel of insert trigger on same table > 0 then bail
  14139.  
  14140.     if trigger_nestlevel( @trigid ) > 0
  14141.          return 1
  14142.     else
  14143.         return 0
  14144. end
  14145. go
  14146. exec dbo.sp_MS_marksystemobject sp_check_sync_trigger
  14147. go
  14148.  
  14149. --
  14150. -- Name: sp_check_for_sync_trigger
  14151. --
  14152. -- Description: This procedure determines if sync tran trigger is 
  14153. -- being called in the context of an updatable subscription. This 
  14154. -- stored procedure is executed at the Subscriber on the subscription database.
  14155. --
  14156. -- Parameter: Refer to the comments in the create procedure statement
  14157. --
  14158. -- Returns: 1 or 0   0 = success
  14159. --
  14160. -- Security: Public procedure - does subscribe security check. 
  14161. -- NOTE : Is this really used by customers ?
  14162. --
  14163. raiserror('Creating procedure sp_check_for_sync_trigger', 0,1)
  14164. go
  14165. create proc sp_check_for_sync_trigger 
  14166. (
  14167.     @tabid int, 
  14168.     @trigger_op char(10) = NULL OUTPUT
  14169. )
  14170. as
  14171. begin
  14172.     declare @ins_trigid int
  14173.     declare @upd_trigid int
  14174.     declare @del_trigid int
  14175.     declare @retcode int
  14176.  
  14177.     --
  14178.     -- security check
  14179.     --
  14180.     exec @retcode = sp_MSreplcheck_subscribe
  14181.     if @@error <> 0 or @retcode <> 0
  14182.     begin
  14183.         return (1)
  14184.     end
  14185.  
  14186.     select @trigger_op = NULL
  14187.     
  14188.     select @ins_trigid = id from sysobjects where
  14189.         type = N'TR' and name like N'trg_MSsync_ins_%' and parent_obj = @tabid
  14190.     select @upd_trigid = id from sysobjects where
  14191.         type = N'TR' and name like N'trg_MSsync_upd_%' and parent_obj = @tabid
  14192.     select @del_trigid = id from sysobjects where
  14193.         type = N'TR' and name like N'trg_MSsync_del_%' and parent_obj = @tabid
  14194.  
  14195.     if trigger_nestlevel( @ins_trigid ) > 0
  14196.     begin
  14197.          select @trigger_op = 'ins'
  14198.          return 1
  14199.     end
  14200.     else    -- if nestlevel of insert trigger on same table > 0 then bail
  14201.     if trigger_nestlevel( @upd_trigid ) > 0
  14202.     begin
  14203.          select @trigger_op = 'upd'
  14204.          return 1
  14205.     end
  14206.     else
  14207.     if trigger_nestlevel( @del_trigid ) > 0
  14208.     begin
  14209.          select @trigger_op = 'del'
  14210.          return 1
  14211.     end
  14212.     else
  14213.         return 0
  14214. end
  14215. go
  14216. exec dbo.sp_MS_marksystemobject sp_check_for_sync_trigger
  14217. go
  14218.  
  14219. raiserror('Creating procedure sp_MSpad_command', 0,1)
  14220. go
  14221. create proc sp_MSpad_command (
  14222.     @cmd     nvarchar(4000) output,
  14223.     @indent  int = 0)  -- indent for command buffer (for pretty formatting
  14224. as
  14225. BEGIN
  14226.     declare
  14227.         @cnt int
  14228.         ,@num_tabs int
  14229.         ,@num_spaces int
  14230.  
  14231.     select @cmd = N''
  14232.     select @num_tabs = @indent / 4
  14233.     select @num_spaces = @indent % 4
  14234.  
  14235.     select @cnt = 0
  14236.     while (@cnt < @num_tabs)
  14237.     begin
  14238.         select @cmd = @cmd + N'    '
  14239.         select @cnt = @cnt + 1
  14240.     end
  14241.  
  14242.     select @cnt = 0
  14243.     while (@cnt < @num_spaces)
  14244.     begin
  14245.         select @cmd = @cmd + N' '
  14246.         select @cnt = @cnt + 1
  14247.     end
  14248. END
  14249. go
  14250.  
  14251. raiserror('Creating procedure sp_MSflush_command', 0,1)
  14252. go
  14253. create proc sp_MSflush_command
  14254.     @cmd     nvarchar(4000) output,
  14255.     @force   int,     -- 0 = flush if necesssary, 1 = flush always
  14256.     @indent  int = 0  -- indent for command buffer (for pretty formatting
  14257. as
  14258. -- debug
  14259. --    if len(@cmd) >= 4000
  14260. --    begin
  14261. --        raiserror("buffer overflow!", 16, 1)
  14262. --        select @cmd
  14263. --    end
  14264. -- debug
  14265.  
  14266.     if @force = 1 or len( @cmd ) > 3000
  14267.     begin
  14268.         insert into #proctext(procedure_text) values( @cmd )
  14269.         select @cmd = N''
  14270.         if @indent > 0 
  14271.             exec dbo.sp_MSpad_command @cmd output, @indent
  14272.     end
  14273. go
  14274.  
  14275.  
  14276.  
  14277. raiserror('Creating procedure sp_MSget_colinfo', 0,1)
  14278. go
  14279. create proc sp_MSget_colinfo 
  14280.     @objid int,
  14281.     @colid int, 
  14282.     @columns binary(32), 
  14283.     @bGetTextImageInfo tinyint = 0, -- boolean for returning text/image info
  14284.     @colname sysname output, 
  14285.     @ccoltype sysname = null output
  14286. as
  14287.     declare @isset        int
  14288.  
  14289.     if @columns is not NULL
  14290.         -- this code path for synctran procs
  14291.         exec @isset = dbo.sp_isarticlecolbitset @colid, @columns
  14292.     else
  14293.         -- this code path for synctran triggers
  14294.         select @isset = 1
  14295.  
  14296.     if @isset != 0 
  14297.     begin
  14298.         select @colname = c.name, @ccoltype= t.name from syscolumns c, systypes t
  14299.         where id = @objid and colid = @colid and c.xtype = t.xusertype
  14300.         -- when checking replicated columns, text/image datatypes cannot be declared or used locally
  14301.         if (@bGetTextImageInfo = 0) and (@ccoltype in (N'text',N'ntext',N'image'))
  14302.             return 1
  14303.     end
  14304.     else
  14305.     begin
  14306.         select @colname = null, @ccoltype = null
  14307.         return 1
  14308.     end
  14309.  
  14310.     return 0
  14311. go
  14312.  
  14313. raiserror('Creating procedure sp_MSget_col_position ', 0,1)
  14314. go
  14315. create procedure sp_MSget_col_position (
  14316.     @objid int,
  14317.     @columns binary(32), -- should be NULL if processing trigger generation
  14318.     @key     sysname, 
  14319.     @colpos  sysname = NULL output,
  14320.     @art_col int = NULL output,
  14321.     @get_num_col bit = 0,
  14322.     @num_col  int = NULL output,
  14323.     @this_col int = null output
  14324. )
  14325. as
  14326. BEGIN  
  14327.     declare @colname      sysname
  14328.             ,@ccoltype     sysname
  14329.             ,@rc           int
  14330.     
  14331.     select @num_col = 0
  14332.     --
  14333.     -- Use a cursor to walk through the columns
  14334.     --
  14335.     DECLARE #hCColid CURSOR LOCAL FAST_FORWARD FOR 
  14336.         select colid, name from syscolumns where id = @objid order by colid asc
  14337.     OPEN #hCColid
  14338.     FETCH #hCColid INTO @this_col, @colname
  14339.     WHILE (@@fetch_status <> -1)
  14340.     begin
  14341.         if @columns is NULL
  14342.         begin
  14343.             --
  14344.             -- processing updating trigger generation on subscriber.
  14345.             -- all columns are to be processed
  14346.             --
  14347.             select @rc = 1
  14348.         end
  14349.         else
  14350.         begin
  14351.             --
  14352.             -- processing updating procedure generation on publisher.
  14353.             -- only replicated columns are to be processed
  14354.             --
  14355.             exec @rc = dbo.sp_isarticlecolbitset @this_col, @columns
  14356.         end
  14357.         if @rc = 1
  14358.         begin
  14359.             select @num_col = @num_col + 1
  14360.             -- If @get_num_col is 1, we just need the number of columns in the partition.
  14361.             if (@get_num_col != 1) and (@colname = @key)
  14362.             begin
  14363.                 select @colpos = 'c' + convert(varchar(4), @this_col)
  14364.                         ,@art_col = @num_col
  14365.                 break
  14366.             end
  14367.         end
  14368.         FETCH #hCColid INTO @this_col, @colname
  14369.     end
  14370.     close #hCColid
  14371.     deallocate #hCColid
  14372.     return 0
  14373. END
  14374. go
  14375. exec dbo.sp_MS_marksystemobject sp_MSget_col_position
  14376. go
  14377.  
  14378. raiserror('Creating procedure sp_MSget_map_position ', 0,1)
  14379. go
  14380. create procedure sp_MSget_map_position 
  14381.     @primary_key_bitmap varbinary(4000) = null,
  14382.     @index int,
  14383.     @colpos  sysname = NULL output,
  14384.     @art_col int = NULL output
  14385. as
  14386.   
  14387.     declare @this_col int
  14388.     declare @num_keys int
  14389.     declare @num_cols int
  14390.     
  14391.     select @this_col = 1
  14392.     select @num_keys = 0
  14393.     select @num_cols = datalength(@primary_key_bitmap) * 8
  14394.  
  14395.     select @colpos = null
  14396.     select @art_col = null
  14397.  
  14398.     while @this_col <= @num_cols
  14399.     begin
  14400.         if (substring(@primary_key_bitmap, 1 + (@this_col-1) / 8 , 1) &
  14401.             power(2, (@this_col-1) % 8 )) <> 0
  14402.         begin
  14403.             select @num_keys = @num_keys + 1
  14404.             if @num_keys = @index
  14405.             begin
  14406.                 select @art_col = @this_col
  14407.                 select @colpos = 'c' + convert(sysname, @this_col)                
  14408.                 break
  14409.             end
  14410.         end
  14411.         select @this_col = @this_col + 1
  14412.     end
  14413. go
  14414.  
  14415. exec dbo.sp_MS_marksystemobject sp_MSget_map_position
  14416. go
  14417.  
  14418. raiserror('Creating procedure sp_MSget_type', 0,1)
  14419. go
  14420. create proc sp_MSget_type 
  14421.     @tabid int, 
  14422.     @colid int, 
  14423.     @colname sysname output, 
  14424.     @typestring nvarchar(4000) output
  14425. as
  14426.     declare @ccolchar       nvarchar(5)
  14427.     declare @coltype        tinyint
  14428.     declare @prec           smallint
  14429.     declare @scale          int
  14430.     declare @ccoltype       sysname
  14431.     declare @xtype          int
  14432.  
  14433.     select @colname = c.name, @xtype = c.xtype, @prec = c.prec, @scale = c.scale,
  14434.         @ccoltype = t.name
  14435.     from syscolumns c, systypes t
  14436.     where c.id = @tabid and c.colid = @colid and 
  14437.         c.xtype = t.xusertype
  14438.      
  14439.     select @typestring = @ccoltype
  14440.  
  14441.     -- datatypes requiring precision (nchar, nvarchar, binary, varbinary)
  14442.     -- format: @var <dt> (prec)
  14443.     if @ccoltype in (N'char',N'nchar', N'varchar', N'nvarchar', N'binary', N'varbinary') 
  14444.         select @typestring = @typestring + N'(' + rtrim(convert(nchar(10),@prec)) + N')'
  14445.  
  14446.     -- datatypes requiring precision & scale (numeric & decimal)
  14447.     -- format: @var <dt> (prec, scale)
  14448.     else if @ccoltype in (N'numeric', N'decimal') 
  14449.         select @typestring = @typestring + N'(' + rtrim(convert(nchar(10),ColumnProperty(@tabid, @colname, 'PRECISION'))) + N',' + 
  14450.             rtrim(convert(nchar(10),@scale)) + N')'
  14451.     
  14452.     -- text/image datatypes cannot be declared or used locally
  14453.     else if @ccoltype in (N'text',N'ntext',N'image')
  14454.         select  @typestring = NULL
  14455. go
  14456.  
  14457. raiserror('Creating procedure sp_MSscript_where_clause', 0,1)
  14458. go
  14459. create procedure sp_MSscript_where_clause (
  14460.     @objid          int,
  14461.     @columns      binary(32), 
  14462.     @clause_type  varchar(15) = 'pk_new', -- 'new pk', 'old pk', 'upd version', 'upd rc', 'trg pk', 'qcft_comp', 'new_pk_q', 'subwins_check'
  14463.     @ts_col       sysname = NULL,
  14464.     @indent       int = 0,
  14465.     @op_type      char(3) = NULL, -- 'ins', 'del', 'upd'
  14466.     @primary_key_bitmap varbinary(4000) = null )
  14467. as
  14468. BEGIN
  14469.     declare    @cmd            nvarchar(4000)
  14470.             ,@colname        sysname
  14471.             ,@ccoltype        sysname
  14472.             ,@spacer        nvarchar(20)
  14473.             ,@indkey        int
  14474.             ,@indid            int
  14475.             ,@key            sysname
  14476.             ,@rc            int
  14477.             ,@this_col        int
  14478.             ,@art_col        int
  14479.             ,@src_cols        int
  14480.             ,@total_col        int
  14481.             ,@col            sysname
  14482.             ,@qualname        nvarchar(512)
  14483.             ,@curparam        nvarchar(20)
  14484.             ,@retcode        int
  14485.             ,@fcreatedcolmap    bit
  14486.     declare @colmap table (relativeorder int identity(1,1), colid int)
  14487.  
  14488.     select @spacer = N' '
  14489.         ,@cmd = N''
  14490.         ,@indkey = 1
  14491.         ,@indid = 0
  14492.         ,@fcreatedcolmap = 0
  14493.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  14494.     select @src_cols = max(colid)
  14495.             ,@total_col = count(colid)
  14496.         from syscolumns where id = @objid
  14497.     exec dbo.sp_MSpad_command @cmd output, @indent
  14498.     if (@clause_type = 'qcft_comp')
  14499.         select @cmd = @cmd + N' '' where '
  14500.     else
  14501.         select @cmd = @cmd + N'where'
  14502.     exec dbo.sp_MSflush_command @cmd output, 1, @indent
  14503.  
  14504.     if @clause_type in ('new pk','old pk','upd version','trg pk','version pk','qcft_comp','new_pk_q','subwins_check')
  14505.     begin
  14506.         if @primary_key_bitmap is null
  14507.         begin
  14508.             exec @indid = dbo.sp_MStable_has_unique_index @objid
  14509.             if @indid is null
  14510.             begin
  14511.                 raiserror('Debug: Cannot find unique index', 16, -1)
  14512.                 return (1)
  14513.             end
  14514.         end
  14515.  
  14516.         --
  14517.         -- check if column Id match relative column order
  14518.         -- for specific trigger operations
  14519.         --
  14520.         if ((@total_col < @src_cols) and (@clause_type = 'trg pk') and 
  14521.             (@columns is null) and (@primary_key_bitmap is not null))
  14522.         begin
  14523.             --
  14524.             -- this table may have altered columns, so when we need to 
  14525.             -- set a mapping for using the bitmaps properly as the bitmap
  14526.             -- always refers relative column order
  14527.             --
  14528.             insert into @colmap (colid)
  14529.                 select colid from syscolumns where id = @objid order by colid
  14530.             if (@@error != 0)
  14531.             begin
  14532.                 raiserror('Could not create column mapping', 16, -1)
  14533.                 return (1)
  14534.             end
  14535.             select @fcreatedcolmap = 1
  14536.         end
  14537.         
  14538.         while (1=1)
  14539.         begin
  14540.             --
  14541.             -- get the column position
  14542.             --
  14543.                 if @primary_key_bitmap is null 
  14544.                 begin
  14545.                          select @key = index_col(@qualname, @indid, @indkey)
  14546.                          if @key is null
  14547.                              break
  14548.                          --exec dbo.sp_MSget_col_position @objid, @columns, @key, @col output, @this_col output
  14549.                          exec dbo.sp_MSget_col_position @objid, @columns, @key, @col output, NULL, 0, NULL, @this_col output
  14550.                 end
  14551.                 else
  14552.                 begin
  14553.                     exec dbo.sp_MSget_map_position @primary_key_bitmap, @indkey, @col output, @this_col output
  14554.                     if @this_col is null
  14555.                         break
  14556.  
  14557.                 --
  14558.                 -- set the actual column id for this relative order in the PK bitmap if necessary
  14559.                 --
  14560.                 if (@fcreatedcolmap = 1)
  14561.                 begin
  14562.                     select @this_col = colid
  14563.                         ,@col = 'c' + convert(sysname, colid) 
  14564.                     from @colmap 
  14565.                     where relativeorder = @this_col 
  14566.                 end
  14567.                 end
  14568.  
  14569.             --
  14570.             -- Get column name
  14571.             --
  14572.             exec @retcode = dbo.sp_MSget_colinfo @objid, @this_col, @columns, 0, @key output, @ccoltype output
  14573.             if (@retcode = 1)
  14574.             begin
  14575.                 --
  14576.                 -- this column not used for replication
  14577.                 -- continue
  14578.                 --
  14579.                 select @indkey = @indkey + 1
  14580.                 continue
  14581.             end
  14582.         
  14583.             if @clause_type = 'new pk'
  14584.             begin
  14585.                 if ColumnProperty(@objid, @key, 'IsIdentity') = 1
  14586.                     select @cmd = @cmd + @spacer + quotename(@key) + N' = @@identity'
  14587.                 else
  14588.                     select @cmd = @cmd + @spacer + quotename(@key) + N' = @' + @col
  14589.  
  14590.                 select @spacer = ' and '
  14591.             end
  14592.             else if @clause_type in ('upd version', 'subwins_check')
  14593.             begin
  14594.                 select @cmd = @cmd + @spacer + quotename(@key) + N' = @' + @col + N'_old'
  14595.                 select @spacer = ' and '
  14596.             end
  14597.             else if @clause_type = 'version pk'
  14598.             begin
  14599.                 select @cmd = @cmd + @spacer + @qualname + '.' + quotename(@key) + N' = inserted.' + quotename(@key)
  14600.                 select @spacer = ' and
  14601.     '
  14602.             end
  14603.             else if @clause_type in ('trg pk', 'old pk')
  14604.             begin                
  14605.                 if @op_type = 'ins'
  14606.                     select @cmd = @cmd + @spacer + quotename(@key) + N' = @' + @col + N'_old'
  14607.                 else
  14608.                     -- The vars correspoding to pk were set in sp_MSscript
  14609.                     -- _pkvar_assignment.
  14610.                     select @cmd = @cmd + @spacer + quotename(@key) + N' = @' + @col 
  14611.                 select @spacer = ' and
  14612.     '
  14613.             end
  14614.             else if (@clause_type = 'qcft_comp')
  14615.             begin
  14616.                 --
  14617.                 -- Conflict compensation generation
  14618.                 -- This is a special case - we generate
  14619.                 -- and exec string for the WHERE clause
  14620.                 --
  14621.                 if (@op_type = 'ins')
  14622.                     select @curparam = N'@' + @col
  14623.                 else if (@op_type = 'del')
  14624.                     select @curparam = N'@' + @col + N'_old'
  14625.                 else
  14626.                     select @curparam = N'ISNULL(@' + @col + N', @' + @col + N'_old)'
  14627.                 
  14628.                 select @cmd = @cmd + @spacer + quotename(@key)
  14629.                 
  14630.                 if (lower(@ccoltype collate SQL_Latin1_General_CP1_CS_AS) = 'varchar')
  14631.                     select @cmd = @cmd + N' = '' + '''''''' + master.dbo.fn_MSgensqescstr(' + @curparam + N') collate database_default + '''''''' '
  14632.                 else if (lower(@ccoltype collate SQL_Latin1_General_CP1_CS_AS) = 'nvarchar')
  14633.                     select @cmd = @cmd + N' = '' + ''N'''''' + master.dbo.fn_MSgensqescstr(' + @curparam + N') collate database_default + '''''''' '
  14634.                 else if (lower(@ccoltype collate SQL_Latin1_General_CP1_CS_AS) = 'char')
  14635.                     select @cmd = @cmd + N' = '' + '''''''' + master.dbo.fn_MSgensqescstr(CAST(RTRIM(' + @curparam + N') as nvarchar)) collate database_default + '''''''' '
  14636.                 else if (lower(@ccoltype collate SQL_Latin1_General_CP1_CS_AS) = 'nchar')
  14637.                     select @cmd = @cmd + N' = '' + ''N'''''' + master.dbo.fn_MSgensqescstr(CAST(RTRIM(' + @curparam + N') as nvarchar)) collate database_default + '''''''' '
  14638.                 else if (lower(@ccoltype collate SQL_Latin1_General_CP1_CS_AS) in ('binary','varbinary'))
  14639.                     select @cmd = @cmd + N' = '' + master.dbo.fn_varbintohexstr(' + @curparam + N') collate database_default ' 
  14640.                 else if (lower(@ccoltype collate SQL_Latin1_General_CP1_CS_AS) in ('bit','bigint','int','smallint','tinyint','decimal','numeric'))
  14641.                     select @cmd = @cmd + N' = '' + CAST(' + @curparam + N' as nvarchar) '
  14642.                 else if (lower(@ccoltype collate SQL_Latin1_General_CP1_CS_AS) in ('float','real'))
  14643.                     select @cmd = @cmd + N' = '' + CONVERT(nvarchar(60),' + @curparam + N', 2) '
  14644.                 else if (lower(@ccoltype collate SQL_Latin1_General_CP1_CS_AS) in ('money','smallmoney'))
  14645.                     select @cmd = @cmd + N' = '' + CONVERT(nvarchar(40),' + @curparam + N', 2) '
  14646.                 else if (lower(@ccoltype collate SQL_Latin1_General_CP1_CS_AS) = 'uniqueidentifier')
  14647.                     select @cmd = @cmd + N' = '' + '''''''' + CAST(' + @curparam + N' as nvarchar(40)) + '''''''' '
  14648.                 else if (lower(@ccoltype collate SQL_Latin1_General_CP1_CS_AS) in ('datetime','smalldatetime'))
  14649.                     select @cmd = @cmd + N' = '' + '''''''' + CONVERT(nvarchar(40), ' + @curparam + N', 112) + N'' '' + CONVERT(nvarchar(40), ' + @curparam + N', 114) + '''''''' '    
  14650.                 else if (lower(@ccoltype collate SQL_Latin1_General_CP1_CS_AS) = 'sql_variant')
  14651.                     select @cmd = @cmd + N' = '' + master.dbo.fn_sqlvarbasetostr(' + @curparam + N' ) collate database_default '
  14652.                 else
  14653.                     select @cmd = @cmd + N' = '' + CAST(' + @curparam + N' as nvarchar) '
  14654.                 
  14655.                 select @spacer = ' + '' and  '
  14656.             end
  14657.             else if @clause_type = 'new_pk_q'
  14658.             begin
  14659.                 --
  14660.                 -- new value of primary key, ignore identity
  14661.                 -- used for scripting in synctran procs
  14662.                 --
  14663.                 select @cmd = @cmd + @spacer + quotename(@key) + N' = @' + @col
  14664.                 select @spacer = ' and '
  14665.             end
  14666.             select @indkey = @indkey + 1
  14667.  
  14668.             -- flush command if necessary
  14669.             exec dbo.sp_MSflush_command @cmd output, 1, @indent
  14670.         end -- end of while loop
  14671.         
  14672.         -- add version col as necessary
  14673.         if ((@clause_type in ('upd version','subwins_check')) and (@ts_col is not null))
  14674.         begin
  14675.             --
  14676.             -- @ts_col is version col actually.
  14677.             -- check for special cases for queued processing
  14678.             --
  14679.             exec dbo.sp_MSget_col_position @objid, @columns, @ts_col, @col output
  14680.             if (@clause_type = 'subwins_check')
  14681.                 select @cmd = @cmd + @spacer + @ts_col + N' = @' + @col
  14682.             else
  14683.                 select @cmd = @cmd + @spacer + @ts_col + N' = @' + @col + N'_old'
  14684.  
  14685.             --
  14686.             -- save off command fragment
  14687.             --
  14688.             exec dbo.sp_MSflush_command @cmd output, 1, @indent
  14689.         end
  14690.     end -- end of if clause_type
  14691.     -- 'upd rc' is used for column value conflict detection. It is no longer used.
  14692.     else if @clause_type = 'upd rc'
  14693.     begin
  14694.         select @this_col = 1, @art_col = 1
  14695.         while @this_col <= @src_cols
  14696.         begin
  14697.             exec @rc = dbo.sp_MSget_colinfo @objid, @this_col, @columns, 0, @colname output, @ccoltype output
  14698.             if @rc = 0
  14699.             begin
  14700.                 select @cmd = @cmd +  @spacer + '(' + @colname + N' = @c' + convert(varchar(4), @this_col) + N'_old or (' 
  14701.                 select @cmd = @cmd + @colname + ' is null and @c' + convert(varchar(4), @this_col) + N'_old is null)) '
  14702.                 select @spacer = N' and 
  14703.     '
  14704.                 exec dbo.sp_MSflush_command @cmd output, 0, @indent
  14705.             end
  14706.             exec dbo.sp_MSflush_command @cmd output, 1, @indent
  14707.             select @this_col = @this_col + 1
  14708.         end
  14709.  
  14710.         -- save off cmd fragment
  14711.         exec dbo.sp_MSflush_command @cmd output, 1, @indent
  14712.     end
  14713.     
  14714. END
  14715. go
  14716. EXEC dbo.sp_MS_marksystemobject sp_MSscript_where_clause
  14717. GO
  14718.  
  14719. raiserror('Creating procedure sp_MSscript_params', 0,1)
  14720. go
  14721. create procedure sp_MSscript_params (
  14722.     @objid   int,
  14723.     @columns binary(32),
  14724.     @postfix nvarchar(8) = NULL,
  14725.     @bOutParams tinyint = 0, -- boolean indicating wether or not to declare timestamp/identity params as output params
  14726.     @outvars nvarchar(4000) = NULL output)
  14727. as
  14728. BEGIN
  14729.     declare @cmd          nvarchar(4000)
  14730.     declare @colname      sysname
  14731.     declare @typestring   nvarchar(4000)
  14732.     declare @spacer       nvarchar(1)
  14733.     declare @spacer2      nvarchar(1)
  14734.     declare @this_col     int
  14735.     declare @art_col      int
  14736.     declare @isset        int
  14737.     declare @pkcolumns    binary(32)
  14738.     declare @ispkcol      int
  14739.  
  14740.     select @spacer = N' '        
  14741.     select @spacer2 = N' '
  14742.     select @art_col = 1
  14743.     select @outvars = null
  14744.     select @cmd = N'    '
  14745.  
  14746.     exec dbo.sp_getarticlepkcolbitmap @objid, @pkcolumns output
  14747.  
  14748.     DECLARE hCColid CURSOR LOCAL FAST_FORWARD FOR 
  14749.     select colid from syscolumns where id = @objid order by colid asc
  14750.  
  14751.     OPEN hCColid
  14752.  
  14753.     FETCH hCColid INTO @this_col
  14754.  
  14755.     WHILE (@@fetch_status <> -1)
  14756.     begin
  14757.  
  14758.         if @columns is not null
  14759.             exec @isset = dbo.sp_isarticlecolbitset @this_col, @columns
  14760.         else
  14761.             select @isset = 1
  14762.  
  14763.         exec @ispkcol = dbo.sp_isarticlecolbitset @this_col, @pkcolumns
  14764.  
  14765.         if @isset != 0 and EXISTS (select name from syscolumns where id=@objid and colid=@this_col and (iscomputed<>1 or @ispkcol<>0)) 
  14766.         begin
  14767.             exec dbo.sp_MSget_type @objid, @this_col, @colname output, @typestring OUTPUT
  14768.             if (@typestring IS NOT NULL)
  14769.             begin
  14770.                 if @postfix is null
  14771.                     select @cmd = @cmd + @spacer + N'@c' + convert(varchar(4), @this_col) + N' ' + @typestring 
  14772.                 else
  14773.                     -- old vars
  14774.                     select @cmd = @cmd + @spacer + N'@c' + convert(varchar(4), @this_col) + @postfix + N' ' + @typestring
  14775.  
  14776.                 -- new vars of type timestamp and identity are declared as output params
  14777.                 if @bOutParams = 1 and (@typestring = N'timestamp' or ColumnProperty(@objid, @colname, 'IsIdentity') = 1)
  14778.                 begin
  14779.                     select @cmd = @cmd + N' output'
  14780.                     select @outvars = isnull(@outvars, N'') + @spacer2 + N'@c' + convert(varchar(4), @this_col) + N' = ' + @colname 
  14781.                     select @spacer2 = N','
  14782.                 end
  14783.                 
  14784.                 select @spacer = N','
  14785.             end
  14786.             select @art_col = @art_col + 1
  14787.  
  14788.             -- flush command if necessary
  14789.             exec dbo.sp_MSflush_command @cmd output, 1, 4
  14790.        end
  14791.        FETCH hCColid INTO @this_col
  14792.     end
  14793.     CLOSE hCColid
  14794.     DEALLOCATE hCColid
  14795.  
  14796. END
  14797. go
  14798.  
  14799. --
  14800. -- proc to generate the other param declarations and
  14801. -- initial proc declarations and assignments for
  14802. -- synctran/queued updating procs
  14803. --
  14804. raiserror('Creating procedure sp_MSscript_procbodystart', 0,1)
  14805. go
  14806. create procedure sp_MSscript_procbodystart (
  14807.     @queued_pub        bit = 0
  14808. )
  14809. as
  14810. BEGIN
  14811.     declare @cmd          nvarchar(4000)
  14812.  
  14813.     --
  14814.     -- script the initial declarations and assignments
  14815.     --
  14816.     select @cmd = N'    ,@execution_mode tinyint = 0)
  14817. AS
  14818. BEGIN
  14819.     set nocount on
  14820.     declare    @retcode int
  14821.         , @rowcount int
  14822.         , @error int
  14823.         , @reinit int
  14824.         , @cmd nvarchar(4000)'
  14825.     exec dbo.sp_MSflush_command @cmd output, 1
  14826.  
  14827.     select @cmd = N'
  14828.     declare    @immediate tinyint '
  14829.     if (@queued_pub = 1)
  14830.     begin
  14831.         select @cmd = @cmd + N' 
  14832.         , @QFirstPass tinyint
  14833.         , @QPubWins tinyint
  14834.         , @QSubWins tinyint
  14835.         , @QReinit tinyint
  14836.         , @cftcase int
  14837. '
  14838.     end
  14839.     exec dbo.sp_MSflush_command @cmd output, 1
  14840.  
  14841.     select @cmd = N' 
  14842.     select     @immediate = 0 '
  14843.     if (@queued_pub = 1)
  14844.     begin
  14845.         select @cmd = @cmd + N'     
  14846.         , @QFirstPass = 1
  14847.         , @QPubWins  = 2
  14848.         , @QSubWins = 3
  14849.         , @QReinit = 4
  14850. '
  14851.     end    
  14852.     exec dbo.sp_MSflush_command @cmd output, 1
  14853.  
  14854.     return 0
  14855. END
  14856. go
  14857. EXEC dbo.sp_MS_marksystemobject sp_MSscript_procbodystart
  14858. GO
  14859.  
  14860.  
  14861. raiserror('Creating procedure sp_MSscript_begintrig1', 0,1)
  14862. go
  14863. create procedure sp_MSscript_begintrig1 (
  14864.     @trigname sysname
  14865.     ,@objid int
  14866.     ,@procname sysname
  14867.     ,@filter_clause nvarchar(4000)
  14868.     ,@op_type char(3) = 'ins' -- ins, upd, del
  14869.     ,@fisqueued bit = 0 -- 1 = Queued subscription
  14870. )
  14871. as
  14872. BEGIN
  14873.     declare @cmd       nvarchar(4000)
  14874.             ,@start     int
  14875.             ,@sub_len   int
  14876.             ,@subtableowner sysname
  14877.             ,@qualname  nvarchar(512)
  14878.  
  14879.     select @subtableowner = user_name(objectproperty(@objid, N'OwnerId'))
  14880.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  14881.  
  14882.     -- construct trigger name
  14883.     select @cmd = N'create trigger ' + QUOTENAME(@trigname) + N' on ' + @qualname + N' for '
  14884.     select @cmd = case
  14885.                     when (@op_type = 'ins') then @cmd + N'insert '
  14886.                     when (@op_type = 'upd') then @cmd + N'update '
  14887.                     when (@op_type = 'del') then @cmd + N'delete '
  14888.                 end
  14889.     select @cmd = @cmd + N'not for replication
  14890. as
  14891. '
  14892.     insert into #proctext(procedure_text) values (@cmd)
  14893.  
  14894.     --
  14895.     -- declare common local variables
  14896.     --
  14897.     --        ,@update_mode char(40)
  14898.     --        ,@failover_mode char(10)
  14899.     --
  14900.     insert into #proctext(procedure_text) values (N'
  14901.     declare     @rc int
  14902.         ,@retcode int
  14903.         ,@connect_string nvarchar(2000)
  14904.         ,@rpc_proc nvarchar(4000)
  14905.         ,@rpc_types nvarchar(4000)
  14906.         ,@update_mode_id int
  14907.         ,@bitmap varbinary(4000)
  14908.         ,@version_guid uniqueidentifier
  14909.         ,@trigger_op char(10) ')
  14910.  
  14911.         --
  14912.         -- queued specific declarations
  14913.         --
  14914.     insert into #proctext(procedure_text) values (N'
  14915.         ,@failover_mode_id int
  14916.         ,@queue_server sysname
  14917.         ,@queue_id sysname
  14918.         ,@tran_id varchar(255)
  14919.         ,@subscriber sysname
  14920.         ,@subscriber_db sysname 
  14921.         ,@partial_cmd bit
  14922.         ,@start_offset int
  14923.         ,@end_offset int
  14924.         ,@vb_buffer varbinary(8000)
  14925.         ,@vb_bufferlen int        
  14926.         ')
  14927.  
  14928.     -- script variables used to retrieve data from inserted table
  14929.     if @op_type in ('ins', 'upd')
  14930.     begin
  14931.         insert into #proctext(procedure_text) values(N'
  14932.     declare ')
  14933.             exec dbo.sp_MSscript_params @objid, null, null, 0, null
  14934.     end
  14935.     insert into #proctext(procedure_text) values(N'
  14936.     declare ')
  14937.     exec dbo.sp_MSscript_params @objid, null, '_old',  0, null
  14938.  
  14939.     -- Set @rc, @subscriber and @subscriber_db
  14940.     -- Optimization. Return immediately if no row changed
  14941.     select @cmd = N'
  14942.  
  14943.     select @rc = @@ROWCOUNT, @subscriber = @@SERVERNAME, @subscriber_db = db_name() 
  14944.     if @rc = 0 
  14945.         return 
  14946.     set nocount on '
  14947.     insert into #proctext(procedure_text) values(@cmd)
  14948.         
  14949.     -- set column update bitmap for update trigger
  14950.     if @op_type in ('upd')
  14951.     begin
  14952.         declare     @num_bytes        int
  14953.                 ,@i_byte            int
  14954.                 ,@i_bit            tinyint
  14955.                 ,@len_before nvarchar(10)
  14956.                 ,@len_after nvarchar(10)
  14957.                 ,@index1 nvarchar(10)
  14958.                 ,@index2 nvarchar(10)
  14959.                 ,@this_col         int
  14960.                 ,@max_col            int
  14961.                 ,@total_col        int
  14962.  
  14963.         --
  14964.         -- check if the subscriber table was altered for column changes
  14965.         --
  14966.         select @max_col = max(colid)
  14967.                 ,@total_col = count(colid)
  14968.             from syscolumns where id = @objid
  14969.         if (@total_col = @max_col)
  14970.         begin
  14971.             --
  14972.             -- actual colid and relative column order are same
  14973.             --
  14974.             insert into #proctext(procedure_text) values(N'
  14975.     select @bitmap = columns_updated() 
  14976.     ')
  14977.         end
  14978.         else
  14979.         begin
  14980.             --
  14981.             -- we need to convert the columns_updated bitmap to 
  14982.             -- a bitmap that contains relative column information
  14983.             --
  14984.             select @cmd = N'
  14985.     select @bitmap = fn_repladjustcolumnmap( ' + cast(@objid as sysname) + N', ' +
  14986.                 cast(@total_col as sysname) + N', columns_updated())'
  14987.             insert into #proctext(procedure_text) values(@cmd)
  14988.             select @cmd = N'                
  14989.     if (@bitmap is null) 
  14990.     begin
  14991.         raiserror(''fn_repladjustcolumnmap could not create column mapping'', 16, 1)
  14992.         goto FAILURE
  14993.     end
  14994.     '
  14995.             insert into #proctext(procedure_text) values(@cmd)
  14996.         end
  14997.  
  14998.             --
  14999.             -- Mark the version bit in the bitmap as updated.
  15000.             --
  15001.             select @cmd = N'
  15002.     ' + '-- set the bit for msrepl_tran_version'
  15003.         insert into #proctext(procedure_text) values(@cmd)
  15004.  
  15005.         -- get actual column id
  15006.         exec dbo.sp_MSget_col_position @objid, null, 'msrepl_tran_version', @this_col = @this_col output
  15007.         if (@total_col < @max_col)
  15008.         begin
  15009.             --
  15010.             -- this table has altered columns, create a mapping between
  15011.             -- relative column position and actual column id
  15012.             --
  15013.             declare @colmap table (relativeorder int identity(1,1), colid int)
  15014.             insert into @colmap (colid)
  15015.                 select colid from syscolumns where id = @objid order by colid
  15016.             if (@@error != 0)
  15017.             begin
  15018.                 raiserror('Could not create column mapping', 16, -1)
  15019.                 return (1)
  15020.             end
  15021.  
  15022.             --
  15023.             -- get the relative column position for msrepl_tran_version
  15024.             --
  15025.             select @this_col = relativeorder from @colmap where colid = @this_col 
  15026.         end
  15027.     
  15028.         select @num_bytes = @total_col / 8 + 1
  15029.             ,@i_byte = 1 + (@this_col-1) / 8
  15030.             ,@i_bit  = power(2, (@this_col-1) % 8 )
  15031.  
  15032.         select @len_before = convert(nvarchar(10), @i_byte -1)
  15033.             ,@index1 = convert(nvarchar(10), @i_byte)
  15034.             ,@index2 = convert(nvarchar(10), @i_byte + 1)
  15035.             ,@len_after = convert(nvarchar(10), @num_bytes - @i_byte)
  15036.  
  15037.         select @cmd = N'
  15038.     select @bitmap = substring(@bitmap, 1, ' + @len_before + 
  15039.             ') + (convert(binary(1), substring(@bitmap, ' + @index1 + 
  15040.             ', 1) | convert(tinyint,' + convert(nvarchar(10), @i_bit) + 
  15041.             '))) + substring(@bitmap, ' + @index2 + 
  15042.             ', ' + @len_after + 
  15043.             ') '
  15044.         exec dbo.sp_MSflush_command @cmd, 1
  15045.     end
  15046.  
  15047.     select @cmd = N'
  15048.     select @version_guid = newid() '
  15049.     insert into #proctext(procedure_text) values(@cmd) 
  15050.  
  15051.     -- Partition check statement
  15052.     if @filter_clause IS NOT NULL
  15053.     begin
  15054.         declare @retcode int
  15055.         exec @retcode = sp_MSsubst_filter_names NULL, N'inserted', @filter_clause output
  15056.         if @retcode <> 0 or @@error <> 0
  15057.             return 1        
  15058.                 
  15059.         select @cmd = N'
  15060.     if exists (select * from inserted where not ('
  15061.         insert into #proctext(procedure_text) values(@cmd) 
  15062.             
  15063.         -- break filter_clause into chunks of 255
  15064.         select @start = 1
  15065.         while @start < len(@filter_clause)
  15066.         begin
  15067.             if len(@filter_clause) < 255
  15068.                 select @sub_len = len(@filter_clause)
  15069.             else
  15070.                 select @sub_len = 255
  15071.             select @cmd = substring(@filter_clause, @start, @sub_len)
  15072.             exec dbo.sp_MSflush_command @cmd output, 1
  15073.             select @start = @start + @sub_len
  15074.         end
  15075.                 
  15076.         select @cmd = N'))
  15077.      begin 
  15078.          exec sp_MSreplraiserror 21034
  15079.          goto FAILURE 
  15080.      end '
  15081.         insert into #proctext(procedure_text) values(@cmd) 
  15082.     end
  15083.  
  15084.     -- trigger nesting checks
  15085.     if @op_type in ('upd')
  15086.     begin
  15087.         select @cmd = N'
  15088.     ' + '-- trigger nesting check
  15089.     ' + '-- error = -1, nested call = 1, not a nested call = 0
  15090.     exec @retcode = dbo.sp_check_sync_trigger @@procid, @trigger_op OUTPUT, N'''
  15091.     + master.dbo.fn_MSgensqescstr(@subtableowner) collate database_default + ''' 
  15092.     if (@retcode = -1)
  15093.         goto FAILURE 
  15094.     if (@retcode = 1)
  15095.         return '
  15096.         insert into #proctext(procedure_text) values(@cmd) 
  15097.     end
  15098. END
  15099. go
  15100.  
  15101. raiserror('Creating procedure sp_MSscript_begintrig2', 0,1)
  15102. go
  15103. create procedure sp_MSscript_begintrig2 (
  15104.     @publisher sysname
  15105.     ,@publisher_db sysname
  15106.     ,@publication sysname
  15107.     ,@objid int
  15108.     ,@op_type char(3) = 'ins' -- ins, upd, del
  15109.     ,@agent_id int
  15110.     ,@fisqueued bit = 0 -- 1 = Queued subscription
  15111. )
  15112. as
  15113. BEGIN
  15114.     declare @cmd nvarchar(4000)
  15115.             ,@queue_server sysname
  15116.             ,@subtableowner sysname
  15117.  
  15118.     select @subtableowner = user_name(objectproperty(@objid, N'OwnerId'))
  15119.  
  15120.     if @op_type = 'ins' 
  15121.     begin
  15122.         insert into #proctext(procedure_text) values(N'
  15123.     if Objectproperty(@@procid,''TriggerInsertOrder'') != 1    
  15124.     begin
  15125.         declare @trigname sysname
  15126.         select @trigname = object_name(@@procid)
  15127.  
  15128.         raiserror (21128, 16, 1, @trigname)
  15129.         goto FAILURE
  15130.     end ')
  15131.     end
  15132.     else if @op_type = 'upd' 
  15133.     begin
  15134.         insert into #proctext(procedure_text) values(N'
  15135.     if Objectproperty(@@procid,''TriggerUpdateOrder'') != 1    
  15136.     begin
  15137.         declare @trigname sysname
  15138.         select @trigname = object_name(@@procid)
  15139.  
  15140.         raiserror (21129, 16, 1, @trigname)
  15141.         goto FAILURE
  15142.     end ')
  15143.     end
  15144.     else if @op_type = 'del' 
  15145.     begin
  15146.         insert into #proctext(procedure_text) values(N'
  15147.     if Objectproperty(@@procid,''TriggerDeleteOrder'') != 1
  15148.     begin
  15149.         declare @trigname sysname
  15150.         select @trigname = object_name(@@procid)
  15151.  
  15152.         raiserror (21130, 16, 1, @trigname)
  15153.         goto FAILURE
  15154.     end ')
  15155.     end
  15156.  
  15157.     --
  15158.     -- scripting for debug messages
  15159.     --
  15160.     select @cmd = N'
  15161.     select @update_mode_id = update_mode 
  15162.     from dbo.MSsubscription_agents where id = ' + convert(nvarchar(10), @agent_id) + N' '
  15163.     insert into #proctext(procedure_text) values (@cmd)
  15164.  
  15165.     --
  15166.     -- continue with scripting
  15167.     --
  15168.     select @cmd = N'
  15169.     ' + N'--
  15170.     ' + N'-- initialize and validate based on update mode
  15171.     ' + N'--
  15172.     if @update_mode_id = 1
  15173.     begin
  15174.         exec @retcode = dbo.sp_MSget_publisher_rpc @@procid, @connect_string output, N'''
  15175.             + master.dbo.fn_MSgensqescstr(@subtableowner) collate database_default + ''' 
  15176.         if @retcode <>0 or @@error <> 0 goto FAILURE
  15177.     end'
  15178.     insert into #proctext(procedure_text) values (@cmd)
  15179.  
  15180.     --
  15181.     -- continue with scripting
  15182.     --
  15183.     if (@fisqueued = 1)
  15184.     begin
  15185.         --
  15186.         -- Queued specific scripting
  15187.         --
  15188.         select @cmd = N'
  15189.     else if @update_mode_id in (2,4)
  15190.     begin
  15191.         select @queue_server = queue_server, @queue_id = queue_id from dbo.MSsubscription_agents where id = ' + convert(nvarchar(10), @agent_id) + N'
  15192.         if (@queue_id is NULL) 
  15193.             goto FAILURE
  15194.     end'
  15195.         insert into #proctext(procedure_text) values (@cmd)
  15196.  
  15197.         --
  15198.         -- continue with scripting
  15199.         --
  15200.         select @cmd = N'
  15201.     else if @update_mode_id in (3,5)
  15202.     begin
  15203.         select @queue_server = queue_server, @queue_id = queue_id from dbo.MSsubscription_agents 
  15204.             where id = ' + convert(nvarchar(10), @agent_id) + N' and failover_mode = 1 '
  15205.         insert into #proctext(procedure_text) values (@cmd)
  15206.  
  15207.         --
  15208.         -- continue with scripting
  15209.         --
  15210.         select @cmd = N'
  15211.         if (@queue_id is NULL)
  15212.         begin
  15213.             exec @retcode = dbo.sp_MSget_publisher_rpc @@procid, @connect_string output, N'''
  15214.                     + master.dbo.fn_MSgensqescstr(@subtableowner) collate database_default + ''' 
  15215.             if @retcode <>0 or @@error <> 0 
  15216.                 goto FAILURE
  15217.         end
  15218.     end'
  15219.         insert into #proctext(procedure_text) values (@cmd)
  15220.     end
  15221.     
  15222.     --
  15223.     -- continue with scripting
  15224.     --
  15225.     select @cmd = N'
  15226.     else if @update_mode_id = 0
  15227.     begin
  15228.         raiserror (''read only mode - no updates allowed'', 16, 1)
  15229.         goto FAILURE
  15230.     end
  15231.     else
  15232.     begin
  15233.         raiserror(''invalid update mode %d'', 16, 1, @update_mode_id)
  15234.         goto FAILURE
  15235.     end '
  15236.     insert into #proctext(procedure_text) values (@cmd)
  15237.  
  15238.     if (@fisqueued = 1)
  15239.     begin        
  15240.         select @cmd = N'
  15241.     ' + N'--
  15242.     ' + N'-- set queue prefix for MSMQ cases
  15243.     ' + N'--
  15244.     if (@update_mode_id in (2,3))
  15245.     begin
  15246.         select @queue_id = N''DIRECT=OS:'' + @queue_server + N''\PRIVATE$\'' + @queue_id 
  15247.     end'
  15248.         insert into #proctext(procedure_text) values (@cmd)
  15249.  
  15250.         --
  15251.         -- Get failover mode scripting
  15252.         --
  15253.         select @cmd = N'
  15254.     ' + N'--
  15255.     ' + N'-- get failover mode
  15256.     ' + N'--
  15257.     if @update_mode_id in (3,5)
  15258.     begin
  15259.         select @failover_mode_id = failover_mode
  15260.         from dbo.MSsubscription_agents where id = '
  15261.         + convert(nvarchar(10), @agent_id) + ' and update_mode in (3,5)
  15262.     end'
  15263.         insert into #proctext(procedure_text) values (@cmd)
  15264.     end
  15265.     
  15266.     --
  15267.     -- Start the distributed tran and get the transaction id as we may use
  15268.     -- it for queue sends
  15269.     --
  15270.     select @cmd = N'
  15271.     ' + N'--
  15272.     ' + N'-- begin tran or dist tran based on update mode
  15273.     ' + N'--
  15274.     if (@update_mode_id in (4,5))
  15275.         BEGIN TRAN
  15276.     else
  15277.         BEGIN DISTRIBUTED TRAN
  15278.     '
  15279.     insert into #proctext(procedure_text) values (@cmd)
  15280.         
  15281.     if (@fisqueued = 1)
  15282.     begin
  15283.         select @cmd = N'
  15284.     ' + N'--
  15285.     ' + N'-- save the transaction token for later use
  15286.     ' + N'--
  15287.     exec sp_getbindtoken @out_token = @tran_id OUTPUT , @for_xp_flag = 1 '
  15288.         insert into #proctext(procedure_text) values (@cmd)
  15289.     end
  15290.  
  15291.     --
  15292.     -- all done with scripting
  15293.     --
  15294.     return 0
  15295. END
  15296. go
  15297.  
  15298. raiserror('Creating procedure sp_MSscript_endtrig', 0,1)
  15299. go
  15300. create proc sp_MSscript_endtrig
  15301. as
  15302. BEGIN
  15303.     declare @cmd nvarchar(4000)
  15304.  
  15305.     select @cmd = N'
  15306.     if (@@trancount > 0)
  15307.         commit tran
  15308.     return 
  15309.  
  15310. FAILURE:
  15311.     if (@@trancount > 0)
  15312.     begin
  15313.         exec sp_MSreplraiserror 20512
  15314.         rollback tran
  15315.     end '
  15316.     insert into #proctext(procedure_text) values(@cmd)
  15317. END
  15318. go
  15319.  
  15320. raiserror('Creating procedure sp_MSscript_trigger_variables', 0,1)
  15321. go
  15322.  
  15323. create procedure sp_MSscript_trigger_variables
  15324. (
  15325.     @objid int,
  15326.     @prefix char(1) = null, -- null or '@'
  15327.     @postfix varchar(4) = null,
  15328.     @indent int = 0,
  15329.     @spacer nvarchar(1) = N' ', 
  15330.     @bOutput_params tinyint = 0,  -- declare output params if necessary
  15331.     @identity_col sysname = null,
  15332.     @ts_col sysname = null,
  15333.     @include_type bit = 0,
  15334.     @set_nulls    bit = 0,
  15335.     @op_type char(3) = 'ins', -- 'ins, 'upd', 'del'
  15336.     @is_new        bit = 0,
  15337.     @primary_key_bitmap varbinary(4000) = NULL,
  15338.     @no_output bit = 0
  15339. )
  15340. as
  15341. begin
  15342.     declare @cmd          nvarchar(4000)
  15343.             ,@colname      sysname
  15344.             ,@ccoltype     sysname
  15345.             ,@src_cols     int
  15346.             ,@this_col     int
  15347.             ,@total_col        int
  15348.             ,@indkey            int
  15349.             ,@fcreatedcolmap    bit
  15350.             ,@rc           int
  15351.             ,@column          nvarchar(4000)
  15352.     declare @colmap table (relativeorder int identity(1,1), colid int)
  15353.  
  15354.     -- script cursor select variables
  15355.     select @cmd = N''
  15356.             ,@indkey = 1
  15357.             ,@fcreatedcolmap = 0
  15358.     select @src_cols = max(colid)
  15359.             ,@total_col = count(colid)
  15360.         from syscolumns where id = @objid
  15361.     exec dbo.sp_MSpad_command @cmd output, @indent
  15362.  
  15363.     --
  15364.     -- check if column Id match relative column order
  15365.     -- for trigger scripting
  15366.     --
  15367.     if (@total_col < @src_cols)
  15368.     begin
  15369.         --
  15370.         -- this table may have altered columns, so when we need to 
  15371.         -- set a mapping for using the bitmaps properly as the bitmap
  15372.         -- always refers relative column order
  15373.         --
  15374.         insert into @colmap (colid)
  15375.             select colid from syscolumns where id = @objid order by colid
  15376.         if (@@error != 0)
  15377.         begin
  15378.             raiserror('Could not create column mapping', 16, -1)
  15379.             return (1)
  15380.         end
  15381.         select @fcreatedcolmap = 1
  15382.     end
  15383.  
  15384.     while (@indkey <= @total_col)
  15385.     begin
  15386.         --
  15387.         -- set the actual column id for this relative order in the bitmap if necessary
  15388.         --
  15389.         if (@fcreatedcolmap = 1)
  15390.         begin
  15391.             select @this_col = colid from @colmap 
  15392.                 where relativeorder = @indkey 
  15393.         end
  15394.         else
  15395.         begin
  15396.             select @this_col = @indkey
  15397.         end
  15398.  
  15399.         --
  15400.         -- Get column name
  15401.         -- Don't include timestamp or computed columns        
  15402.         --
  15403.         exec @rc = dbo.sp_MSget_colinfo @objid, @this_col, null, 0, @colname output, @ccoltype output
  15404.         if @rc = 0 and EXISTS (select name from syscolumns where id=@objid and colid=@this_col and iscomputed<>1 and xtype <> 189)
  15405.         begin
  15406.             if @prefix is null
  15407.             begin
  15408.             
  15409.                 if (@set_nulls = 1)
  15410.                 begin
  15411.                     -- Optimization:
  15412.                     -- Get null or actual column name
  15413.                     -- Note: the output is quoted.
  15414.                     exec dbo.sp_MSget_synctran_column 
  15415.                         @ts_col = @ts_col,
  15416.                         @op_type = @op_type, -- 'ins, 'upd', 'del'
  15417.                         @is_new = @is_new,
  15418.                         @primary_key_bitmap = @primary_key_bitmap,
  15419.                         @colname = @colname,
  15420.                         @this_col = @this_col,
  15421.                         @column = @column output,
  15422.                         @from_proc = 0, 
  15423.                         @coltype = @ccoltype, 
  15424.                         @type = NULL,
  15425.                         @art_col = @indkey
  15426.                     select @cmd = @cmd + @spacer + @column + isnull(@postfix, N'')
  15427.                 end
  15428.                 else
  15429.                 begin
  15430.                     -- set null is false
  15431.                     select @cmd = @cmd + @spacer + N'[' + @colname + isnull(@postfix, N'') + N']'
  15432.                 end
  15433.             end
  15434.             else
  15435.             begin
  15436.                 -- prefix was specified
  15437.                 select @cmd = @cmd + @spacer + isnull(@prefix, N'') 
  15438.                     + N'c' + RTRIM(convert(nvarchar(4), @this_col)) + isnull(@postfix, N'')
  15439.             end
  15440.  
  15441.             if (@include_type = 1)
  15442.             begin
  15443.                 declare @typestring nvarchar(100)
  15444.                 exec dbo.sp_MSget_type @objid, @this_col, @colname output, @typestring OUTPUT
  15445.                 select @cmd = @cmd +  N' ' + @typestring 
  15446.             end
  15447.  
  15448.             -- new vars of type timestamp and identity are declared as output params
  15449.             if (@bOutput_params = 1 and (@ccoltype = N'timestamp' or ColumnProperty(@objid, @colname, 'IsIdentity') = 1))
  15450.                 or (@colname = @identity_col or @colname = @ts_col)
  15451.             begin
  15452.                 -- YWU: Do this to avoid output in cursor declaration statement.
  15453.                 -- The right thing seems to be set output only when bOutput_params is set
  15454.                 -- but it seems not the way this sp is called.
  15455.                 if @set_nulls = 0 and @no_output = 0
  15456.                     select @cmd = @cmd + N' output'
  15457.             end
  15458.  
  15459.             select @spacer = N','
  15460.         end -- if rc=0 and exists ...
  15461.         
  15462.         exec dbo.sp_MSflush_command @cmd output, 0, @indent
  15463.         select @indkey = @indkey + 1
  15464.     end -- while () loop
  15465.  
  15466.     exec dbo.sp_MSflush_command @cmd output, 1, @indent
  15467.     insert into #proctext(procedure_text) values(N'
  15468. ') 
  15469.  
  15470. end
  15471. go
  15472.  
  15473. raiserror('Creating procedure sp_MSscript_trigger_assignment', 0,1)
  15474. go
  15475.  
  15476. create procedure sp_MSscript_trigger_assignment (
  15477.     @objid int
  15478.     ,@postfix char(4) = null
  15479.     ,@indent int = 0
  15480.     ,@ts_col sysname
  15481.     ,@op_type char(3) -- 'ins, 'upd', 'del'
  15482.     ,@is_new    bit
  15483.     ,@primary_key_bitmap varbinary(4000) = null
  15484. )
  15485. as
  15486. BEGIN
  15487.     declare @cmd          nvarchar(4000)
  15488.             ,@colname      sysname
  15489.             ,@spacer       nvarchar(1)
  15490.             ,@ccoltype     sysname
  15491.             ,@src_cols     int
  15492.             ,@this_col     int
  15493.             ,@total_col        int
  15494.             ,@indkey            int
  15495.             ,@fcreatedcolmap    bit
  15496.             ,@rc           int
  15497.             ,@column          nvarchar(4000)
  15498.     declare @colmap table (relativeorder int identity(1,1), colid int)
  15499.  
  15500.     -- initialize
  15501.     select @spacer = N' '
  15502.             ,@indkey = 1
  15503.             ,@fcreatedcolmap = 0
  15504.     select @src_cols = max(colid)
  15505.             ,@total_col = count(colid)
  15506.         from syscolumns where id = @objid
  15507.     exec dbo.sp_MSpad_command @cmd output, @indent
  15508.  
  15509.     --
  15510.     -- check if column Id match relative column order
  15511.     -- for trigger scripting
  15512.     --
  15513.     if (@total_col < @src_cols)
  15514.     begin
  15515.         --
  15516.         -- this table may have altered columns, so when we need to 
  15517.         -- set a mapping for using the bitmaps properly as the bitmap
  15518.         -- always refers relative column order
  15519.         --
  15520.         insert into @colmap (colid)
  15521.             select colid from syscolumns where id = @objid order by colid
  15522.         if (@@error != 0)
  15523.         begin
  15524.             raiserror('Could not create column mapping', 16, -1)
  15525.             return (1)
  15526.         end
  15527.         select @fcreatedcolmap = 1
  15528.     end
  15529.  
  15530.     while (@indkey <= @total_col)
  15531.     begin
  15532.         --
  15533.         -- set the actual column id for this relative order in the bitmap if necessary
  15534.         --
  15535.         if (@fcreatedcolmap = 1)
  15536.         begin
  15537.             select @this_col = colid from @colmap 
  15538.                 where relativeorder = @indkey 
  15539.         end
  15540.         else
  15541.         begin
  15542.             select @this_col = @indkey
  15543.         end
  15544.  
  15545.         --
  15546.         -- Get column name
  15547.         --
  15548.         exec @rc = dbo.sp_MSget_colinfo @objid, @this_col, null, 0, @colname output, @ccoltype output
  15549.         if @rc = 0  and EXISTS (select name from syscolumns where id=@objid and @this_col=colid and iscomputed<>1)
  15550.         begin
  15551.             -- Optimization:
  15552.             -- Get null or actual column name
  15553.             -- Note: the output is quoted.
  15554.             exec dbo.sp_MSget_synctran_column 
  15555.                 @ts_col = @ts_col,
  15556.                 @op_type = @op_type, -- 'ins, 'upd', 'del'
  15557.                 @is_new = @is_new,
  15558.                 @primary_key_bitmap = @primary_key_bitmap,
  15559.                 @colname = @colname,
  15560.                 @this_col = @this_col,
  15561.                 @column = @column output,
  15562.                 @from_proc = 0, 
  15563.                 @coltype = NULL, 
  15564.                 @type = NULL,
  15565.                 @art_col = @indkey
  15566.  
  15567.             select @cmd = @cmd + @spacer + N'@c' + 
  15568.                 convert(sysname, @this_col) + isnull(@postfix, N'') + 
  15569.                 N' = ' + @column  
  15570.                 
  15571.             select @spacer = N','
  15572.         end
  15573.         exec dbo.sp_MSflush_command @cmd output, 1, @indent
  15574.         select @indkey = @indkey + 1
  15575.     end
  15576.     exec dbo.sp_MSflush_command @cmd output, 1, @indent
  15577.  
  15578. END
  15579. go
  15580.  
  15581. raiserror('Creating procedure sp_MSscript_trigger_fetch_statement', 0,1)
  15582. go
  15583.  
  15584. create procedure sp_MSscript_trigger_fetch_statement (
  15585.     @objid   int, 
  15586.     @op_type char(3) = 'ins',
  15587.     @indent   int = 0
  15588. )
  15589. as
  15590. BEGIN
  15591.     declare @cmd          nvarchar(4000)
  15592.  
  15593.     -- script fetch statements
  15594.     if @op_type in ('ins', 'upd')
  15595.     begin
  15596.         exec dbo.sp_MSpad_command @cmd output, @indent
  15597.         select @cmd = @cmd + N'fetch next from rpl_ins_cursor into 
  15598. '
  15599.         exec dbo.sp_MSflush_command @cmd output, 1, @indent
  15600.         exec dbo.sp_MSscript_trigger_variables @objid, '@', null, @indent, ' '
  15601.     end
  15602.  
  15603.     if @op_type in ('ins')
  15604.     begin
  15605.         exec dbo.sp_MSpad_command @cmd output, @indent
  15606.         select @cmd = @cmd + N'fetch next from rpl_ins2_cursor into 
  15607. '
  15608.         exec dbo.sp_MSflush_command @cmd output, 1, @indent
  15609.         exec dbo.sp_MSscript_trigger_variables @objid, '@', '_old', @indent, ' '
  15610.     end
  15611.  
  15612.     if @op_type in ('upd', 'del')
  15613.     begin
  15614.         exec dbo.sp_MSpad_command @cmd output, @indent
  15615.         select @cmd = @cmd + N'fetch next from rpl_del_cursor into 
  15616. '
  15617.         exec dbo.sp_MSflush_command @cmd output, 1, @indent
  15618.         exec dbo.sp_MSscript_trigger_variables @objid, '@', '_old', @indent, ' '
  15619.     end
  15620. END
  15621. go
  15622.  
  15623. raiserror('Creating procedure sp_MSscript_trigger_exec_rpc ', 0,1)
  15624. go
  15625. create procedure sp_MSscript_trigger_exec_rpc (
  15626.     @publisher   sysname,
  15627.     @publisherdb sysname,
  15628.     @publication sysname,
  15629.     @procname   sysname,
  15630.     @proc_owner sysname,
  15631.     @cftproc    sysname,
  15632.     @objid       int, 
  15633.     @op_type     char(3) = 'ins', 
  15634.     @indent      int = 0,
  15635.     @identity_col sysname = null,
  15636.     @ts_col       sysname = null,
  15637.     @primary_key_bitmap   varbinary(4000),
  15638.     @pubversion int
  15639. )
  15640. as
  15641. BEGIN
  15642.     declare @cmd nvarchar(4000)
  15643.             ,@min_identity int
  15644.             ,@max_identity int
  15645.             ,@fisqueued bit
  15646.             ,@varindent int
  15647.             ,@object_owner sysname
  15648.  
  15649.     --
  15650.     -- validate @op_type
  15651.     --
  15652.     if (@op_type) not in ('ins', 'upd', 'del')
  15653.         return 1    
  15654.     select @fisqueued = case when (@cftproc is NULL) then 0 else 1 end
  15655.     --
  15656.     -- Set version guid param and column first.
  15657.     --
  15658.     if @op_type in ('upd')
  15659.     begin
  15660.         exec dbo.sp_MSscript_trigger_version_updates @objid, 'msrepl_tran_version', @indent,
  15661.             @primary_key_bitmap
  15662.     end
  15663.  
  15664.     --
  15665.     -- continue scripting
  15666.     --
  15667.     select @cmd = N'
  15668.         if (@update_mode_id = 1) or (@update_mode_id in (3, 5) and @failover_mode_id = 0)
  15669.         begin 
  15670.             ' + N'-- 
  15671.             ' + N'-- immediate mode - check if publisher is local
  15672.             ' + N'-- 
  15673.             if @connect_string is null 
  15674.             begin '
  15675.     insert into #proctext(procedure_text) values (@cmd)
  15676.  
  15677.     --
  15678.     -- prepare the proc invocation
  15679.     -- 1st two variables are subscriber server name and database name for cycle detection
  15680.     --
  15681.     select @cmd = N'
  15682.                 select @rpc_proc = N''' + quotename(@publisher) collate database_default + N'.' + 
  15683.                     quotename(master.dbo.fn_MSgensqescstr(@publisherdb)) collate database_default + N'.' + 
  15684.                     quotename(master.dbo.fn_MSgensqescstr(@proc_owner)) collate database_default + N'.' + 
  15685.                     quotename(master.dbo.fn_MSgensqescstr(@procname)) collate database_default + N''' 
  15686.                 exec @retcode = @rpc_proc @subscriber, @subscriber_db,
  15687.             '
  15688.     insert into #proctext(procedure_text) values (@cmd)
  15689.  
  15690.     --
  15691.     -- script the trigger variables
  15692.     --
  15693.     select @min_identity = @@identity
  15694.     if @op_type in ('ins', 'upd')
  15695.         exec dbo.sp_MSscript_trigger_variables @objid, '@', N'', @indent, N'', 0,  @identity_col, @ts_col
  15696.  
  15697.     if @op_type = 'upd'
  15698.     begin
  15699.         exec dbo.sp_MSscript_trigger_variables @objid, '@', '_old', @indent, ',', 0, null, null
  15700.         insert into #proctext(procedure_text) values (N'
  15701.                         ,@bitmap')
  15702.     end
  15703.  
  15704.     else if @op_type = 'del'
  15705.         exec dbo.sp_MSscript_trigger_variables @objid, '@', '_old', @indent, ' ', 0, null, null
  15706.  
  15707.     select @max_identity = @@identity
  15708.     
  15709.     --
  15710.     -- continue scripting
  15711.     --
  15712.     select @cmd = N'
  15713.                 if (@@error != 0 or @retcode != 0)
  15714.                 begin 
  15715.                     if (@retcode = -2)
  15716.                         exec sp_MSreplraiserror 21064
  15717.                     else if @retcode = 5
  15718.                         exec sp_MSreplraiserror 20515
  15719.                     else
  15720.                         exec sp_MSreplraiserror 21054
  15721.                     goto FAILURE 
  15722.                 end
  15723.             end
  15724.             else
  15725.             begin'
  15726.     insert into #proctext(procedure_text) values (@cmd)
  15727.     
  15728.     --
  15729.     -- prepare the RPC invocation
  15730.     --
  15731.     select @cmd = N'
  15732.                 select @rpc_proc = N''
  15733.                 declare @retcode int 
  15734.                 exec @retcode = '' + N'
  15735.     select @cmd = @cmd + quotename('OpenDataSource(''SQLOLEDB'',N' ,'''') 
  15736.     select @cmd = @cmd + '+ '''''''' + replace(@connect_string, '''''''', '''''''''''''''') + N'''''''' + '
  15737.     select @cmd = @cmd + 'N'').'' + N''' 
  15738.     select @cmd = @cmd + quotename(master.dbo.fn_MSgensqescstr(@publisherdb)) collate database_default + '.'
  15739.     select @cmd = @cmd + quotename(master.dbo.fn_MSgensqescstr(@proc_owner)) collate database_default + '.'
  15740.     select @cmd = @cmd + quotename(master.dbo.fn_MSgensqescstr(@procname)) collate database_default + ''' + quotename(@subscriber) collate database_default + '','' + quotename(@subscriber_db) collate database_default + '', '' + 
  15741.                 '''
  15742.     insert into #proctext(procedure_text) values (@cmd)
  15743.  
  15744.     --
  15745.     -- script the trigger variables
  15746.     --
  15747.     select @varindent = @indent + 4
  15748.     if @op_type in ('ins', 'upd')
  15749.         exec dbo.sp_MSscript_trigger_variables @objid, '@', N'', 0, N'', 0,  @identity_col, @ts_col
  15750.  
  15751.     if @op_type = 'upd'
  15752.     begin
  15753.         exec dbo.sp_MSscript_trigger_variables @objid, '@', 'o', @varindent, ',', 0, null, null
  15754.         insert into #proctext(procedure_text) values (N'
  15755.                         ,@bitmap')
  15756.     end
  15757.     else if @op_type = 'del'
  15758.         exec dbo.sp_MSscript_trigger_variables @objid, '@', 'o', 0, ' ', 0, null, null
  15759.  
  15760.     --
  15761.     -- Must raise error right before exiting the dynamic exec so that it will be picked up.
  15762.     --
  15763.     select @cmd = N'
  15764.         '' + '' if (@@error != 0 or @retcode != 0) 
  15765.         begin 
  15766.             if (@retcode = -2) 
  15767.                 exec sp_MSreplraiserror 21064 
  15768.             else if @retcode = 5 
  15769.                 exec sp_MSreplraiserror 20515
  15770.             else 
  15771.                 exec sp_MSreplraiserror 21054 
  15772.         end''
  15773.         '
  15774.     insert into #proctext(procedure_text) values (@cmd)
  15775.  
  15776.     --
  15777.     -- Get parameter datatypes
  15778.     --
  15779.     insert into #proctext(procedure_text) values (N'
  15780.                 select @rpc_types = ''')
  15781.     if @op_type in ('ins', 'upd')
  15782.         exec dbo.sp_MSscript_trigger_variables @objid, '@', N'' , 0, N'', 0,  @identity_col, @ts_col, 1
  15783.     if @op_type = 'upd'
  15784.         exec dbo.sp_MSscript_trigger_variables @objid, '@', 'o', @varindent, ',', 0, null, null, 1
  15785.     else if @op_type = 'del'
  15786.         exec dbo.sp_MSscript_trigger_variables @objid, '@', 'o', 0, ' ', 0, null, null, 1
  15787.     
  15788.     exec dbo.sp_MSpad_command @cmd output, @indent
  15789.     select @cmd = @cmd + N''''
  15790.     insert into #proctext(procedure_text) values (@cmd)
  15791.  
  15792.     if @op_type = 'upd'
  15793.     begin
  15794.         insert into #proctext(procedure_text) values (N'
  15795.                 select @rpc_types = @rpc_types + '', @bitmap varbinary(4000)'' ')
  15796.     end
  15797.  
  15798.     --
  15799.     -- make rpc call
  15800.     --
  15801.     insert into #proctext(procedure_text) values (N'
  15802.                 exec @retcode = dbo.sp_executesql @rpc_proc, @rpc_types, 
  15803. ')
  15804.  
  15805.     --
  15806.     -- Get parameters again
  15807.     --
  15808.     insert into #proctext(procedure_text) select procedure_text from #proctext
  15809.     where c1 > @min_identity and c1 <= @max_identity
  15810.     order by c1 asc
  15811.  
  15812.     --
  15813.     -- continue scripting
  15814.     --
  15815.     select @cmd = N'
  15816.                 if @@error != 0 
  15817.                     goto FAILURE
  15818.             end
  15819.         end '
  15820.     insert into #proctext(procedure_text) values (@cmd)
  15821.  
  15822.     if (@fisqueued = 1)
  15823.     begin
  15824.         declare @artidstring sysname
  15825.             ,@qversion int
  15826.             ,@foldqueuestyle bit
  15827.  
  15828.         --
  15829.         -- Check the publisher version
  15830.         --
  15831.         if (@pubversion = 1)
  15832.         begin
  15833.             --
  15834.             -- Publisher is PreSP3
  15835.             -- Use the new style of parameter passing - Queue version 1
  15836.             --
  15837.             select @foldqueuestyle = 1
  15838.         end
  15839.         else if (@pubversion > 1)
  15840.         begin
  15841.             --
  15842.             -- Publisher is SP3 or later
  15843.             -- get the article id as string
  15844.             -- Use the new style of parameter passing - Queue version 2
  15845.             --
  15846.             select @artidstring = cast(artid as sysname)
  15847.             from (dbo.MSsubscription_articles as a join dbo.MSsubscription_agents as b
  15848.                     on a.agent_id = b.id)
  15849.             where b.publisher = UPPER(@publisher)
  15850.                 and b.publisher_db = @publisherdb
  15851.                 and b.publication = @publication
  15852.                 and a.dest_table = object_name(@objid)
  15853.             select @foldqueuestyle = 0
  15854.         end
  15855.         else
  15856.         begin
  15857.             --
  15858.             -- bad publisher version
  15859.             --
  15860.             return 1
  15861.         end
  15862.         --
  15863.         -- Are we going old style - for backwards compatibility for SQL Queue
  15864.         -- For MSMQ we use a newer clsid for queue version and will
  15865.         -- use whatever is assigned to the queue during its creation
  15866.         -- A newer publisher will imply a newer distributor and we are
  15867.         -- okay.
  15868.         --
  15869.         if (@foldqueuestyle = 1)
  15870.         begin
  15871.             --
  15872.             -- Update the version on the sql queue to v1 if necessary
  15873.             --
  15874.             update dbo.MSsubscription_agents
  15875.             set queue_id = 'mssqlqueue'
  15876.             where publisher = UPPER(@publisher)
  15877.                 and publisher_db = @publisherdb
  15878.                 and publication = @publication
  15879.                 and update_mode in (4,5)
  15880.                 and queue_id != 'mssqlqueue'
  15881.         end
  15882.         else
  15883.         begin
  15884.             --
  15885.             -- Update the version on the sql queue to v2 if necessary
  15886.             --
  15887.             update dbo.MSsubscription_agents
  15888.             set queue_id = 'mssqlqueuev2'
  15889.             where publisher = UPPER(@publisher)
  15890.                 and publisher_db = @publisherdb
  15891.                 and publication = @publication
  15892.                 and update_mode in (4,5)
  15893.                 and queue_id != 'mssqlqueuev2'
  15894.         end
  15895.         --
  15896.         -- continue scripting
  15897.         --
  15898.         select @cmd = N'
  15899.         else
  15900.         begin
  15901.             ' + N'--
  15902.             ' + N'-- handle queued cases
  15903.             ' + N'-- 
  15904.             if (@update_mode_id in (2,3))
  15905.             begin'
  15906.         insert into #proctext(procedure_text) values (@cmd)
  15907.  
  15908.         --
  15909.         -- MSMQ based write
  15910.         --
  15911.         if (@foldqueuestyle = 1)
  15912.         begin
  15913.             --
  15914.             -- old style scripting - non secure
  15915.             --
  15916.             select @cmd = N'
  15917.                 exec @retcode = master.dbo.sp_replsendtoqueue @queue_id, @tran_id, N' + 
  15918.                 quotename(@publication, '''') + N', N' +    
  15919.                 quotename(@cftproc, '''') + N', N' +
  15920.                 quotename(@proc_owner, '''')    + N', N' + 
  15921.                 quotename(@procname, '''') + N', @subscriber, @subscriber_db, 
  15922. '
  15923.         end
  15924.         else
  15925.         begin
  15926.             --
  15927.             -- new style scripting - secure
  15928.             --
  15929.             select @cmd = N'
  15930.                 exec @retcode = master.dbo.sp_replsendtoqueue @queue_id, @tran_id, N' + 
  15931.                 quotename(@publication, '''') + N', N' +    
  15932.                 quotename(@artidstring, '''') + N', N' +
  15933.                 quotename(@op_type, '''')    + N', N' + 
  15934.                 quotename(@procname, '''') + N', @subscriber, @subscriber_db, 
  15935. '
  15936.         end
  15937.         insert into #proctext(procedure_text) values (@cmd)
  15938.  
  15939.         --
  15940.         -- script the trigger variables
  15941.         --
  15942.         select @varindent = @indent + 8
  15943.         select @min_identity = @@identity
  15944.         if @op_type in ('ins', 'upd')
  15945.             exec dbo.sp_MSscript_trigger_variables @objid, '@', N'', @varindent, N'', 0,  @identity_col, @ts_col,
  15946.                 @no_output = 1
  15947.  
  15948.         if @op_type = 'upd'
  15949.         begin
  15950.             exec dbo.sp_MSscript_trigger_variables @objid, '@', '_old', @varindent, ',', 0, null, null,
  15951.                 @no_output = 1
  15952.  
  15953.             insert into #proctext(procedure_text) values (N'
  15954.                     ,@bitmap')
  15955.         end
  15956.  
  15957.         else if @op_type = 'del'
  15958.             exec dbo.sp_MSscript_trigger_variables @objid, '@', '_old', @varindent, ' ', 0, null, null,
  15959.                 @no_output = 1
  15960.  
  15961.         select @max_identity = @@identity
  15962.  
  15963.         --
  15964.         -- SQL Queued case
  15965.         -- we loop here if the command length exceeds queue message length and
  15966.         -- break the command into partial cmds and send it in more than one 
  15967.         -- queue message
  15968.         --
  15969.         select @cmd = N'
  15970.             end
  15971.             else if (@update_mode_id in (4,5))
  15972.             begin
  15973.                 select @partial_cmd = 1, @start_offset = 0, @end_offset = 0
  15974.                 while (@partial_cmd != 0)
  15975.                 begin'
  15976.         insert into #proctext(procedure_text) values (@cmd)
  15977.  
  15978.         if (@foldqueuestyle = 1)
  15979.         begin
  15980.             --
  15981.             -- old style scripting - non secure
  15982.             --
  15983.             select @cmd = N'
  15984.                     exec @retcode = master.dbo.sp_replwritetovarbin @start_offset, @end_offset output, @vb_buffer output, @vb_bufferlen output, N' + 
  15985.                 quotename(@publisher, '''') + N', N' +
  15986.                 quotename(@publisherdb, '''') + N', N' +    
  15987.                 quotename(@publication, '''')    + N', @tran_id, N' +    
  15988.                 quotename(@cftproc, '''')    + N', N' +
  15989.                 quotename(@proc_owner, '''') + N', N' + 
  15990.                 quotename(@procname, '''') + N', @subscriber, @subscriber_db, 
  15991. '
  15992.         end
  15993.         else
  15994.         begin
  15995.             --
  15996.             -- new style scripting - secure
  15997.             --
  15998.             select @cmd = N'
  15999.                     exec @retcode = master.dbo.sp_replwritetovarbin @start_offset, @end_offset output, @vb_buffer output, @vb_bufferlen output, N' + 
  16000.                 quotename(@publisher, '''') + N', N' +    
  16001.                 quotename(@publisherdb, '''') + N', N' +    
  16002.                 quotename(@publication, '''')    + N', @tran_id, N' +    
  16003.                 quotename(@artidstring, '''')    + N', N' +
  16004.                 quotename(@op_type, '''') + N', N' + 
  16005.                 quotename(@procname, '''') + N', @subscriber, @subscriber_db, 
  16006. '
  16007.         end
  16008.         insert into #proctext(procedure_text) values (@cmd)
  16009.  
  16010.         --
  16011.         -- script the trigger variables
  16012.         --
  16013.         select @min_identity = @@identity
  16014.         if @op_type in ('ins', 'upd')
  16015.             exec dbo.sp_MSscript_trigger_variables @objid, '@', N'', @varindent, N'', 0,  @identity_col, @ts_col,
  16016.                 @no_output = 1
  16017.  
  16018.         if @op_type = 'upd'
  16019.         begin
  16020.             exec dbo.sp_MSscript_trigger_variables @objid, '@', '_old', @varindent, ',', 0, null, null,
  16021.                 @no_output = 1
  16022.  
  16023.             insert into #proctext(procedure_text) values (N'
  16024.                     ,@bitmap')
  16025.         end
  16026.  
  16027.         else if @op_type = 'del'
  16028.             exec dbo.sp_MSscript_trigger_variables @objid, '@', '_old', @varindent, ' ', 0, null, null,
  16029.                 @no_output = 1
  16030.  
  16031.         select @max_identity = @@identity
  16032.  
  16033.         --
  16034.         -- continue scripting
  16035.         --
  16036.         select @cmd = N'
  16037.                     if @@error != 0 or @retcode != 0 
  16038.                     begin 
  16039.                         exec sp_MSreplraiserror 21052
  16040.                         goto FAILURE 
  16041.                     end'
  16042.         insert into #proctext(procedure_text) values(@cmd)
  16043.  
  16044.         --
  16045.         -- handle partial messages
  16046.         --
  16047.         select @object_owner = user_name(ObjectProperty(@objid, 'ownerid'))
  16048.         select @cmd = N'
  16049.                     select @partial_cmd = case when (@end_offset > 0) then 1 else 0 end            
  16050.                     exec @retcode = sp_MSsendtosqlqueue @@procid, N' + 
  16051.                         quotename(@publisher, '''') + N', N' + 
  16052.                         quotename(@publisherdb, '''') + N', N' + 
  16053.                         quotename(@publication, '''') + N', N' +
  16054.                         quotename(@object_owner, '''') +
  16055.                         N', @tran_id, @vb_buffer, @vb_bufferlen, 1, @partial_cmd '
  16056.         insert into #proctext(procedure_text) values(@cmd)
  16057.  
  16058.         --
  16059.         -- continue scripting
  16060.         --
  16061.         select @cmd = N'
  16062.                     if @@error != 0 or @retcode != 0 
  16063.                     begin 
  16064.                         exec sp_MSreplraiserror 21052
  16065.                         goto FAILURE 
  16066.                     end
  16067.                     select @start_offset = @end_offset
  16068.                 end
  16069.             end'
  16070.         insert into #proctext(procedure_text) values(@cmd)
  16071.  
  16072.         --
  16073.         -- continue scripting
  16074.         --
  16075.         select @cmd = N'
  16076.             if @@error <>0 or @retcode <> 0 
  16077.             begin 
  16078.                 exec sp_MSreplraiserror 21052
  16079.                 goto FAILURE 
  16080.             end
  16081.         end
  16082.     '
  16083.         insert into #proctext(procedure_text) values(@cmd)
  16084.     end
  16085.     
  16086.     --
  16087.     -- all done
  16088.     --
  16089.     return 0
  16090. END
  16091. go
  16092.  
  16093. raiserror('Creating procedure sp_MSscript_trigger_update_checks', 0,1)
  16094. go
  16095.  
  16096. create procedure sp_MSscript_trigger_update_checks(
  16097.     @objid int,
  16098.     @identity_col sysname,
  16099.     @ts_col       sysname,
  16100.     @op_type varchar(3) = 'ins', -- 'ins', 'upd'
  16101.     @indent int = 0
  16102. )
  16103. as
  16104. BEGIN
  16105.     declare @cmd          nvarchar(4000)
  16106.     declare @colname      sysname
  16107.     declare @ccoltype     sysname
  16108.     declare @src_cols     int
  16109.     declare @this_col     int
  16110.     declare @rc           int
  16111.     declare @qualname     nvarchar(512)
  16112.     declare @indid        int
  16113.     declare @key          sysname
  16114.     declare @indkey       int
  16115.  
  16116. /*
  16117.     if @op_type = 'pk'
  16118.     begin
  16119.         select @indkey = 1
  16120.         exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  16121.         exec @indid = dbo.sp_MStable_has_unique_index @objid
  16122.         if @indid > 0
  16123.           begin
  16124.             exec dbo.sp_MSpad_command @cmd output, @indent
  16125.             while @indkey < 16 and index_col(@qualname, @indid, @indkey) is not null
  16126.             begin
  16127.                 select @key = index_col(@qualname, @indid, @indkey)
  16128.                 select @cmd = N'if update(' + @key + N')
  16129. '
  16130.                 exec dbo.sp_MSflush_command @cmd output, 1, @indent
  16131.                 insert into #proctext(procedure_text) values(N'begin
  16132.      exec sp_MSreplraiserror 20517
  16133.      goto FAILURE
  16134.  end 
  16135.  
  16136. ')
  16137.                 select @indkey = @indkey + 1
  16138.             end
  16139.         end
  16140.     end
  16141.     else
  16142.     begin
  16143.  */
  16144.     -- Image cols
  16145.     select @src_cols = max(colid) from syscolumns where id = @objid
  16146.     select @this_col = 1
  16147.     exec dbo.sp_MSpad_command @cmd output, @indent
  16148.    
  16149.         while @this_col <= @src_cols
  16150.         begin
  16151.             exec @rc = dbo.sp_MSget_colinfo @objid, @this_col, null, 1, @colname output, @ccoltype output
  16152.             if @rc = 0  and EXISTS (select name from syscolumns where id=@objid and @this_col=colid and iscomputed<>1)
  16153.             begin
  16154.                 if @ccoltype in ('text','ntext','image')
  16155.                 begin
  16156.                 if @op_type = 'ins'
  16157.                     begin
  16158.                         select @cmd = N'if update(' +  quotename(@colname) + ') 
  16159. '
  16160.                         exec dbo.sp_MSflush_command @cmd output, 1, 0
  16161.                         insert into #proctext(procedure_text) values(N'    exec sp_MSreplraiserror 20508
  16162. ')
  16163.                     end
  16164.                     else if @op_type = 'upd'
  16165.                     begin
  16166.                         select @cmd = N'if update(' +  quotename(@colname) + ') 
  16167.                         exec dbo.sp_MSflush_command @cmd output, 1, 0
  16168.                         insert into #proctext(procedure_text) values(N'begin
  16169.      exec sp_MSreplraiserror 20509
  16170.      goto FAILURE 
  16171.  end
  16172.  
  16173. ')
  16174.                     end
  16175.                 end
  16176.             end
  16177.             select @this_col = @this_col + 1
  16178.         end
  16179.  --   end
  16180.  
  16181.     -- identity col
  16182.     if @op_type = 'upd' and @identity_col is not null
  16183.     begin
  16184.         select @cmd = N'if update(' +  quotename(@identity_col) + N') 
  16185. '
  16186.         exec dbo.sp_MSflush_command @cmd, 1
  16187.         insert into #proctext(procedure_text) values(N'begin
  16188.      exec sp_MSreplraiserror 20510
  16189.      goto FAILURE
  16190.  end
  16191.  
  16192. ')
  16193.     end
  16194.  
  16195.     -- timestamp col
  16196.     if @op_type = 'upd' and @ts_col is not null
  16197.     begin
  16198.         select @cmd = N'if update(' +  quotename(@ts_col) + N') 
  16199. '
  16200.         exec dbo.sp_MSflush_command @cmd, 1
  16201.         insert into #proctext(procedure_text) values(N'begin
  16202.      exec sp_MSreplraiserror 20511
  16203.      goto FAILURE
  16204.  end
  16205.  
  16206. ')
  16207.     end
  16208. END
  16209. go    
  16210.  
  16211. raiserror('Creating procedure sp_MSscript_trigger_updates', 0,1)
  16212. go
  16213. create procedure sp_MSscript_trigger_updates
  16214.     @identity_col sysname,
  16215.     @ts_col       sysname,
  16216.     @op_type      char(3) = 'ins', -- 'ins', 'del'
  16217.     @objid        int,
  16218.     @indent       int = 0,
  16219.     @primary_key_bitmap varbinary(4000) = null
  16220. as
  16221.     declare @cmd nvarchar(4000)
  16222.     declare @col sysname
  16223.     declare @qualname nvarchar(512)
  16224.  
  16225.     if @op_type = 'upd'
  16226.     begin
  16227.         -- Script out pk var assigment that used in sp_MSscript_where_clause
  16228.         exec dbo.sp_MSscript_pkvar_assignment @objid, NULL, 1, @identity_col, @ts_col, 
  16229.             @primary_key_bitmap
  16230.  
  16231.         insert into #proctext(procedure_text) values(N'
  16232.     ')
  16233.     end
  16234.  
  16235.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  16236.  
  16237.     if @ts_col is not null and OBJECTPROPERTY(@objid, 'tablehastimestamp') <> 1
  16238.     begin
  16239.         insert into #proctext(procedure_text) values(N' 
  16240. ')
  16241.         exec dbo.sp_MSpad_command @cmd output, @indent
  16242.         exec dbo.sp_MSget_col_position @objid, null, @ts_col, @col output
  16243.         select @cmd = @cmd + N'update ' + @qualname + N' set ' + @ts_col + N' = @' + @col
  16244.         exec dbo.sp_MSflush_command @cmd, 1
  16245.  
  16246.         exec dbo.sp_MSscript_where_clause @objid, null, 'trg pk', null, @indent, @op_type, @primary_key_bitmap
  16247.     end
  16248.  
  16249.    -- Reset to publisher's identity value if it is not an identity at the subscriber
  16250.    if @op_type = 'ins' and @identity_col is not null and OBJECTPROPERTY(@objid, 'tablehasidentity') <> 1
  16251.     begin
  16252.         insert into #proctext(procedure_text) values(N' 
  16253. ')
  16254.         exec dbo.sp_MSpad_command @cmd output, @indent
  16255.         exec dbo.sp_MSget_col_position @objid, null, @identity_col, @col output
  16256.         select @cmd = @cmd + N'update ' + @qualname + N' set ' + @identity_col + N' = @' + @col
  16257.         exec dbo.sp_MSflush_command @cmd, 1
  16258.  
  16259.         exec dbo.sp_MSscript_where_clause @objid, null, 'trg pk', null, @indent, @op_type, @primary_key_bitmap
  16260.     end
  16261. go
  16262.  
  16263. raiserror('Creating procedure sp_MSscript_trigger_version_updates', 0,1)
  16264. go
  16265. create procedure sp_MSscript_trigger_version_updates
  16266.     @objid        int,
  16267.     @version_col  sysname,
  16268.     @indent       int = 0,
  16269.     @primary_key_bitmap   varbinary(4000)
  16270. as
  16271.     declare @cmd nvarchar(4000)
  16272.     declare @col sysname
  16273.     declare @qualname nvarchar(512)
  16274.  
  16275.     -- Script out pk var assigment that used in sp_MSscript_where_clause
  16276.     exec dbo.sp_MSscript_pkvar_assignment @objid, NULL, 1, null, null, @primary_key_bitmap
  16277.  
  16278.     insert into #proctext(procedure_text) values(N'
  16279. ')
  16280.  
  16281.     exec dbo.sp_MSget_col_position @objid, null, @version_col, @col output
  16282.  
  16283.     -- Assign the param corresponding to version col to new guid
  16284.     exec dbo.sp_MSpad_command @cmd output, @indent
  16285.     select @cmd = @cmd + N'set @' + @col + N' = @version_guid ' 
  16286.     exec dbo.sp_MSflush_command @cmd, 1
  16287.     insert into #proctext(procedure_text) values(N' 
  16288. ')
  16289.  
  16290.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  16291.     exec dbo.sp_MSpad_command @cmd output, @indent
  16292.     select @cmd = N'update ' + @qualname + N' set ' + @version_col + N' = @' + @col
  16293.     exec dbo.sp_MSflush_command @cmd, 1
  16294.     exec dbo.sp_MSscript_where_clause @objid, null, 'trg pk', null, @indent, 'upd', @primary_key_bitmap
  16295. go
  16296.  
  16297. raiserror('Creating procedure sp_MSscript_singlerow_trigger', 0,1)
  16298. go
  16299. create procedure sp_MSscript_singlerow_trigger (
  16300.     @objid        int,
  16301.     @publisher    sysname,
  16302.     @publisher_db sysname,
  16303.     @publication  sysname,
  16304.     @procname     sysname,
  16305.     @proc_owner      sysname,
  16306.     @cftproc      sysname,
  16307.     @identity_col  sysname,
  16308.     @ts_col        sysname,
  16309.     @op_type char(3) = 'ins', -- 'ins, 'upd', 'del'
  16310.     @primary_key_bitmap varbinary(4000) = NULL,
  16311.     @pubversion int
  16312. )
  16313. as
  16314. BEGIN
  16315.     declare @colname      sysname
  16316.             ,@spacer       nvarchar(1)
  16317.             ,@ccoltype     sysname
  16318.             ,@this_col     int
  16319.             ,@rc           int
  16320.             ,@cmd            nvarchar(4000)
  16321.  
  16322.     --
  16323.     -- script update checks
  16324.     --
  16325.     if @op_type in ('ins', 'upd')
  16326.         exec dbo.sp_MSscript_trigger_update_checks @objid, @identity_col, @ts_col, @op_type, 0
  16327.  
  16328.     --
  16329.     -- continue scripting
  16330.     --
  16331.     select @cmd = N' 
  16332.     ' + N'--
  16333.     ' + N'-- Are we doing single or multi row trigger update 
  16334.     ' + N'--
  16335.     if (@rc = 1)
  16336.     begin 
  16337.         ' + N'--
  16338.         ' + N'-- single row trigger update
  16339.         ' + N'-- '
  16340.     insert into #proctext(procedure_text) values(@cmd)
  16341.  
  16342.     --
  16343.     -- script the trigger assignments
  16344.     --
  16345.     if @op_type in ('ins', 'upd')
  16346.     begin
  16347.         select @cmd = N'
  16348.         select 
  16349. '
  16350.         insert into #proctext(procedure_text) values(@cmd)
  16351.         exec dbo.sp_MSscript_trigger_assignment @objid, null, 8, @ts_col, @op_type, 1, @primary_key_bitmap
  16352.         select @cmd = N'
  16353.         from inserted '
  16354.         insert into #proctext(procedure_text) values(@cmd)    
  16355.     end
  16356.  
  16357.     if @op_type in ('ins')
  16358.     begin
  16359.         select @cmd = N'
  16360.         select 
  16361. '
  16362.         insert into #proctext(procedure_text) values(@cmd)
  16363.         exec dbo.sp_MSscript_trigger_assignment @objid, '_old', 8, @ts_col, @op_type, 0, @primary_key_bitmap
  16364.         select @cmd = N'
  16365.         from inserted '
  16366.         insert into #proctext(procedure_text) values(@cmd)    
  16367.     end
  16368.     else if @op_type in ('upd', 'del')
  16369.     begin
  16370.         select @cmd = N'
  16371.         select 
  16372. '
  16373.         insert into #proctext(procedure_text) values(@cmd)
  16374.         exec dbo.sp_MSscript_trigger_assignment @objid, '_old', 8, @ts_col, @op_type, 0, @primary_key_bitmap
  16375.         select @cmd = N'
  16376.         from deleted '
  16377.         insert into #proctext(procedure_text) values(@cmd)    
  16378.     end
  16379.  
  16380.     --
  16381.     -- script the execution logic
  16382.     --
  16383.     exec dbo.sp_MSscript_trigger_exec_rpc @publisher, @publisher_db, @publication, @procname, @proc_owner, 
  16384.                 @cftproc, @objid, @op_type, 12, @identity_col, @ts_col, @primary_key_bitmap, @pubversion
  16385.             
  16386.     --
  16387.     -- script any updates to be done
  16388.     --
  16389.     if @op_type in ('ins', 'upd')
  16390.         exec dbo.sp_MSscript_trigger_updates @identity_col, @ts_col, @op_type, @objid, 8, @primary_key_bitmap
  16391.  
  16392.     --
  16393.     -- script the end (for single row change)
  16394.     -- 
  16395.     select @cmd = N'
  16396.     end -- end of single row trigger update '
  16397.     insert into #proctext(procedure_text) values(@cmd)
  16398.  
  16399.     --
  16400.     -- all done
  16401.     --
  16402.     return 0
  16403. END
  16404. go
  16405.  
  16406. raiserror('Creating procedure sp_MSscript_multirow_trigger', 0,1)
  16407. go
  16408. create procedure sp_MSscript_multirow_trigger (
  16409.     @objid        int,
  16410.     @publisher    sysname,
  16411.     @publisher_db sysname,
  16412.     @publication  sysname,
  16413.     @procname     sysname,
  16414.     @proc_owner      sysname,
  16415.     @cftproc      sysname,
  16416.     @identity_col  sysname,
  16417.     @ts_col        sysname,
  16418.     @op_type char(3) = 'ins', -- 'ins, 'upd', 'del'
  16419.     @primary_key_bitmap varbinary(4000) = NULL,
  16420.     @pubversion int
  16421. )
  16422. as
  16423. BEGIN
  16424.  
  16425.     declare @cmd          nvarchar(4000)
  16426.  
  16427.     --
  16428.     -- start scripting
  16429.     --
  16430.     select @cmd = N'
  16431.     else
  16432.     begin 
  16433.         ' + N'--
  16434.         ' + N'-- start of multirow row trigger update 
  16435.         ' + N'-- '
  16436.     insert into #proctext(procedure_text) values(@cmd)
  16437.  
  16438.     --
  16439.     -- setup cursor over inserted table for ins & upd triggers
  16440.     --
  16441.     if @op_type in ('ins', 'upd')
  16442.     begin
  16443.         select @cmd = N'
  16444.         declare rpl_ins_cursor CURSOR LOCAL FAST_FORWARD FOR select 
  16445. '
  16446.         insert into #proctext(procedure_text) values(@cmd)
  16447.  
  16448.         exec dbo.sp_MSscript_trigger_variables @objid, null, null, 8, ' ',
  16449.             0,@identity_col, @ts_col,0, 1, @op_type, 1, @primary_key_bitmap
  16450.  
  16451.         select @cmd = N'
  16452.         from inserted for read only
  16453.         open rpl_ins_cursor 
  16454. '
  16455.         insert into #proctext(procedure_text) values(@cmd)
  16456.     end
  16457.  
  16458.     if @op_type in ('ins')
  16459.     begin
  16460.         select @cmd = N'
  16461.         declare rpl_ins2_cursor CURSOR LOCAL FAST_FORWARD FOR select 
  16462. '
  16463.         insert into #proctext(procedure_text) values(@cmd)
  16464.  
  16465.         exec dbo.sp_MSscript_trigger_variables @objid, null, null, 8, ' '
  16466.  
  16467.         select @cmd = N'
  16468.         from inserted for read only
  16469.         open rpl_ins2_cursor 
  16470. '
  16471.         insert into #proctext(procedure_text) values(@cmd)
  16472.     end
  16473.  
  16474.     --
  16475.     -- setup cursor over deleted table for  upd & del triggers
  16476.     --
  16477.     if @op_type in ('upd', 'del')
  16478.     begin
  16479.         select @cmd = N'
  16480.         declare rpl_del_cursor CURSOR LOCAL FAST_FORWARD FOR select 
  16481. '
  16482.         insert into #proctext(procedure_text) values(@cmd)
  16483.  
  16484.         exec dbo.sp_MSscript_trigger_variables @objid, null, null, 8, ' ', 
  16485.             0,@identity_col, @ts_col,0, 1,  @op_type, 0, @primary_key_bitmap
  16486.  
  16487.         select @cmd = N'
  16488.         from deleted for read only
  16489.         open rpl_del_cursor 
  16490. '
  16491.         insert into #proctext(procedure_text) values(@cmd)
  16492.     end
  16493.  
  16494.     --
  16495.     -- script fetch statement
  16496.     --
  16497.     exec dbo.sp_MSscript_trigger_fetch_statement @objid, @op_type, 8
  16498.  
  16499.     --
  16500.     -- start the fetch loop
  16501.     --
  16502.     select @cmd = N'
  16503.         while (@@fetch_status != -1)
  16504.         begin '
  16505.     insert into #proctext(procedure_text) values(@cmd)
  16506.  
  16507.     --
  16508.     -- script the execution logic
  16509.     --
  16510.     exec dbo.sp_MSscript_trigger_exec_rpc @publisher, @publisher_db, @publication, @procname, @proc_owner, 
  16511.             @cftproc, @objid, @op_type, 16, @identity_col, @ts_col, @primary_key_bitmap, @pubversion
  16512.  
  16513.     --
  16514.     -- script any updates to be done
  16515.     --
  16516.     if @op_type in ('ins', 'upd')
  16517.         exec dbo.sp_MSscript_trigger_updates @identity_col, @ts_col, @op_type, @objid, 8, @primary_key_bitmap
  16518.  
  16519.     --
  16520.     -- do the next fetch
  16521.     --
  16522.     insert into #proctext(procedure_text) values(N'
  16523. ')
  16524.     exec dbo.sp_MSscript_trigger_fetch_statement @objid, @op_type, 12
  16525.  
  16526.     --
  16527.     -- release the cursors
  16528.     --
  16529.     select @cmd = N'
  16530.         end  -- cursor while loop'
  16531.     insert into #proctext(procedure_text) values(@cmd)
  16532.  
  16533.     if @op_type in ('ins', 'upd')
  16534.     begin
  16535.         select @cmd = N'
  16536.         close rpl_ins_cursor
  16537.         deallocate rpl_ins_cursor '
  16538.         insert into #proctext(procedure_text) values(@cmd)
  16539.     end
  16540.  
  16541.     if @op_type = 'ins'
  16542.     begin
  16543.         select @cmd = N'
  16544.         close rpl_ins2_cursor
  16545.         deallocate rpl_ins2_cursor '
  16546.         insert into #proctext(procedure_text) values(@cmd)
  16547.     end
  16548.  
  16549.     if @op_type in ('upd', 'del')
  16550.     begin
  16551.         select @cmd = N'
  16552.         close rpl_del_cursor
  16553.         deallocate rpl_del_cursor '
  16554.         insert into #proctext(procedure_text) values(@cmd)        
  16555.     end
  16556.  
  16557.     --
  16558.     -- script the end (for single row change)
  16559.     -- 
  16560.     select @cmd = N'
  16561.     end -- end of multi row trigger update '
  16562.     insert into #proctext(procedure_text) values(@cmd)
  16563.  
  16564.     --
  16565.     -- all done
  16566.     --
  16567.     return 0
  16568.  
  16569. END
  16570. go
  16571.  
  16572. --
  16573. -- Name: sp_MSscript_sync_ins_trig
  16574. --
  16575. -- Description: This proc is used during the scripting of publisher synctran trigger 
  16576. -- used by updating subscribers. This SP generates the script for INSERT synctran 
  16577. -- trigger.It is executed on subscriber during the subscription initialization phase.
  16578. --
  16579. -- Parameter: Refer to the comments in the create procedure statement
  16580. --
  16581. -- Returns: 1 or 0   0 = success
  16582. --
  16583. -- Security: Public procedure - does subscribe security check. 
  16584. --
  16585. raiserror('Creating procedure sp_MSscript_sync_ins_trig', 0,1)
  16586. go
  16587. create procedure sp_MSscript_sync_ins_trig (
  16588.     @objid          int,
  16589.     @publisher    sysname,
  16590.     @publisher_db sysname,
  16591.     @publication  sysname,
  16592.     @trigname     sysname,
  16593.     @procname     sysname,
  16594.     @proc_owner   sysname,
  16595.     @cftproc      sysname,
  16596.     @agent_id      int, 
  16597.     @identity_col sysname = NULL,
  16598.     @ts_col       sysname = NULL,
  16599.     @filter_clause nvarchar(4000),
  16600.     @primary_key_bitmap  varbinary(4000),
  16601.     @pubversion int = 1
  16602. )
  16603. as
  16604. BEGIN
  16605.     declare @colname      sysname
  16606.             ,@cmd          nvarchar(4000)
  16607.             ,@ins_cmd      nvarchar(4000)
  16608.             ,@columns      binary(32)
  16609.             ,@outvars      nvarchar(4000)
  16610.             ,@rc           int
  16611.             ,@qualname     nvarchar(512)
  16612.             ,@fisqueued       bit
  16613.  
  16614.     set nocount on
  16615.     --
  16616.     -- security check
  16617.     --
  16618.     exec @rc = sp_MSreplcheck_subscribe
  16619.     if @@error <> 0 or @rc <> 0
  16620.     begin
  16621.         return (1)
  16622.     end
  16623.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  16624.     if (LOWER(@cftproc) = N'null')
  16625.     begin
  16626.         select @fisqueued =  0
  16627.                 ,@cftproc = NULL
  16628.     end
  16629.     else 
  16630.         select @fisqueued =  1
  16631.  
  16632.     if @ts_col in ('null','NULL')
  16633.         select @ts_col = null
  16634.  
  16635.     if @identity_col in ('null','NULL')
  16636.         select @identity_col = null
  16637.  
  16638.     -- Create temp table
  16639.     create table #proctext ( c1 int identity NOT NULL, procedure_text nvarchar(4000) collate database_default null)
  16640.  
  16641.     -- 1st preamble common to all synctran procs
  16642.     exec dbo.sp_MSscript_begintrig1 @trigname, @objid, @procname, @filter_clause, 'ins', @fisqueued
  16643.                 
  16644.     -- 2nd preamble common to all synctran procs
  16645.     exec dbo.sp_MSscript_begintrig2 @publisher, @publisher_db, @publication, @objid, 'ins',@agent_id, @fisqueued
  16646.  
  16647.     -- script single row handling
  16648.     exec @rc = dbo.sp_MSscript_singlerow_trigger @objid,@publisher, @publisher_db, @publication, @procname, @proc_owner, 
  16649.         @cftproc, @identity_col, @ts_col, 'ins', @primary_key_bitmap, @pubversion
  16650.  
  16651.     -- script multi-row handling
  16652.     exec @rc = dbo.sp_MSscript_multirow_trigger @objid, @publisher, @publisher_db, @publication, @procname, @proc_owner, 
  16653.         @cftproc, @identity_col, @ts_col, 'ins', @primary_key_bitmap, @pubversion
  16654.  
  16655.     -- script end of trigger
  16656.     exec dbo.sp_MSscript_endtrig 
  16657.  
  16658.     -- send fragments to client
  16659.     select procedure_text from #proctext order by c1 asc
  16660. END
  16661. go
  16662. exec dbo.sp_MS_marksystemobject sp_MSscript_sync_ins_trig
  16663. go
  16664.  
  16665. --
  16666. -- Name: sp_MSscript_sync_upd_trig
  16667. --
  16668. -- Description: This proc is used during the scripting of publisher synctran trigger 
  16669. -- used by updating subscribers. This SP generates the script for UPDATE synctran 
  16670. -- trigger.It is executed on subscriber during the subscription initialization phase.
  16671. --
  16672. -- Parameter: Refer to the comments in the create procedure statement
  16673. --
  16674. -- Returns: 1 or 0   0 = success
  16675. --
  16676. -- Security: Public procedure - does subscribe security check. 
  16677. --
  16678. raiserror('Creating procedure sp_MSscript_sync_upd_trig', 0,1)
  16679. go
  16680. create procedure sp_MSscript_sync_upd_trig (
  16681.     @objid        int,
  16682.     @publisher    sysname,
  16683.     @publisher_db sysname,
  16684.     @publication  sysname, 
  16685.     @trigname     sysname,
  16686.     @procname     sysname,
  16687.     @proc_owner   sysname,
  16688.     @cftproc      sysname,
  16689.     @agent_id      int, 
  16690.     @identity_col sysname = NULL,
  16691.     @ts_col       sysname = NULL,
  16692.     @filter_clause nvarchar(4000),
  16693.     @primary_key_bitmap  varbinary(4000),
  16694.     @pubversion int = 1)
  16695. as
  16696. BEGIN
  16697.     declare @colname      sysname
  16698.             ,@cmd          nvarchar(4000)
  16699.             ,@ins_cmd      nvarchar(4000)
  16700.             ,@columns      binary(32)
  16701.             ,@outvars      nvarchar(4000)
  16702.             ,@rc           int
  16703.             ,@qualname     nvarchar(512)
  16704.             ,@fisqueued       bit
  16705.  
  16706.     set nocount on
  16707.     --
  16708.     -- security check
  16709.     --
  16710.     exec @rc = sp_MSreplcheck_subscribe
  16711.     if @@error <> 0 or @rc <> 0
  16712.     begin
  16713.         return (1)
  16714.     end
  16715.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  16716.     if (LOWER(@cftproc) = N'null')
  16717.     begin
  16718.         select @fisqueued =  0
  16719.                 ,@cftproc = NULL
  16720.     end
  16721.     else 
  16722.         select @fisqueued =  1
  16723.  
  16724.     if @ts_col in ('null','NULL')
  16725.         select @ts_col = null
  16726.  
  16727.     if @identity_col in ('null','NULL')
  16728.         select @identity_col = null
  16729.  
  16730.     -- Create temp table
  16731.     create table #proctext ( c1 int identity NOT NULL, procedure_text nvarchar(4000) collate database_default null)
  16732.  
  16733.     -- 1st preamble common to all synctran procs
  16734.     exec dbo.sp_MSscript_begintrig1 @trigname, @objid, @procname, @filter_clause, 'upd', @fisqueued
  16735.                     
  16736.     -- prevent updating of unique index when 'row compare' conflict detection, since it would trickle
  16737.     -- back as a del/insert, and fail
  16738. /*
  16739.     if @ts_col is null
  16740.     begin
  16741.         insert into #proctext(procedure_text) values(N' 
  16742. ')
  16743. --        exec dbo.sp_MSscript_trigger_update_checks @objid, null, null, 'pk', 0
  16744.     end
  16745. */
  16746.  
  16747.     -- 2nd preamble common to all synctran procs
  16748.     exec dbo.sp_MSscript_begintrig2 @publisher, @publisher_db, @publication, @objid, 'upd',@agent_id, @fisqueued
  16749.  
  16750.     -- script single row handling
  16751.     exec @rc = dbo.sp_MSscript_singlerow_trigger @objid,@publisher, @publisher_db, @publication, @procname, @proc_owner, 
  16752.         @cftproc, @identity_col, @ts_col, 'upd', @primary_key_bitmap, @pubversion
  16753.  
  16754.     -- script multi-row handling
  16755.     exec @rc = dbo.sp_MSscript_multirow_trigger @objid,@publisher, @publisher_db, @publication, @procname, @proc_owner, 
  16756.         @cftproc, @identity_col, @ts_col, 'upd', @primary_key_bitmap, @pubversion
  16757.     -- script end of trigger
  16758.     exec dbo.sp_MSscript_endtrig 
  16759.  
  16760.     -- send fragments to client
  16761.     select procedure_text from #proctext order by c1 asc
  16762. END
  16763. go
  16764. exec dbo.sp_MS_marksystemobject sp_MSscript_sync_upd_trig
  16765. go
  16766.  
  16767. --
  16768. -- Name: sp_MSscript_sync_del_trig
  16769. --
  16770. -- Description: This proc is used during the scripting of publisher synctran trigger used by updating subscribers. 
  16771. -- This SP generates the script for DELETE synctran trigger.It is executed on subscriber during the 
  16772. -- subscription initialization phase.
  16773. --
  16774. -- Parameter: Refer to the comments in the create procedure statement
  16775. --
  16776. -- Returns: 1 or 0   0 = success
  16777. --
  16778. -- Security: Public procedure - does subscribe security check. 
  16779. --
  16780. raiserror('Creating procedure sp_MSscript_sync_del_trig', 0,1)
  16781. go
  16782. create procedure sp_MSscript_sync_del_trig (
  16783.     @objid        int,
  16784.     @publisher    sysname,
  16785.     @publisher_db sysname,
  16786.     @publication  sysname, 
  16787.     @trigname     sysname,
  16788.     @procname     sysname,
  16789.     @proc_owner      sysname,
  16790.     @cftproc      sysname,
  16791.     @agent_id      int, 
  16792.     @identity_col sysname = NULL,
  16793.     @ts_col       sysname = NULL,
  16794.     @filter_clause nvarchar(4000),
  16795.     @primary_key_bitmap  varbinary(4000),
  16796.     @pubversion int = 1
  16797. )
  16798. as
  16799. BEGIN
  16800.     declare @colname sysname
  16801.             ,@cmd          nvarchar(4000)
  16802.             ,@ins_cmd      nvarchar(4000)
  16803.             ,@columns      binary(32)
  16804.             ,@outvars      nvarchar(4000)
  16805.             ,@rc           int
  16806.             ,@qualname     nvarchar(512)
  16807.             ,@fisqueued       bit
  16808.  
  16809.     set nocount on
  16810.     --
  16811.     -- security check
  16812.     --
  16813.     exec @rc = sp_MSreplcheck_subscribe
  16814.     if @@error <> 0 or @rc <> 0
  16815.     begin
  16816.         return (1)
  16817.     end
  16818.  
  16819.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  16820.     if (LOWER(@cftproc) = N'null')
  16821.     begin
  16822.         select @fisqueued =  0
  16823.                 ,@cftproc = NULL
  16824.     end
  16825.     else 
  16826.         select @fisqueued =  1
  16827.  
  16828.     if @ts_col in ('null','NULL')
  16829.         select @ts_col = null
  16830.  
  16831.     if @identity_col in ('null','NULL')
  16832.         select @identity_col = null
  16833.  
  16834.     -- Create temp table
  16835.     create table #proctext ( c1 int identity NOT NULL, procedure_text nvarchar(4000) collate database_default null)
  16836.  
  16837.     -- 1st preamble common to all synctran procs
  16838.     exec dbo.sp_MSscript_begintrig1 @trigname, @objid, @procname, @filter_clause, 'del', @fisqueued
  16839.  
  16840.     -- 2nd preamble common to all synctran procs
  16841.     exec dbo.sp_MSscript_begintrig2 @publisher, @publisher_db, @publication, @objid, 'del', @agent_id, @fisqueued
  16842.  
  16843.     -- script single row handling
  16844.     exec @rc = dbo.sp_MSscript_singlerow_trigger @objid,@publisher, @publisher_db, @publication, @procname, @proc_owner, 
  16845.     @cftproc, @identity_col, @ts_col, 'del', @primary_key_bitmap, @pubversion
  16846.  
  16847.     -- script multi-row handling
  16848.     exec @rc = dbo.sp_MSscript_multirow_trigger @objid,@publisher, @publisher_db, @publication, @procname, @proc_owner, 
  16849.     @cftproc, @identity_col, @ts_col, 'del', @primary_key_bitmap, @pubversion
  16850.  
  16851.     -- script end of trigger
  16852.     exec dbo.sp_MSscript_endtrig 
  16853.  
  16854.     -- send fragments to client
  16855.     select procedure_text from #proctext order by c1 asc
  16856. END
  16857. go
  16858. exec dbo.sp_MS_marksystemobject sp_MSscript_sync_del_trig
  16859. go
  16860.  
  16861. raiserror('Creating procedure sp_MSget_synctran_column', 0,1)
  16862. go
  16863. create procedure sp_MSget_synctran_column
  16864. (
  16865.     @ts_col sysname,
  16866.     @op_type char(3), -- 'ins, 'upd', 'del'
  16867.     @is_new    bit,
  16868.     @primary_key_bitmap varbinary(4000) = null,
  16869.     @colname sysname,
  16870.     @this_col int, -- position in source object
  16871.     @column nvarchar(4000) output,
  16872.     @from_proc bit = 0,
  16873.     @coltype sysname = NULL,
  16874.     @type    varchar(10) = NULL,
  16875.     @art_col int = NULL -- position in the partition.
  16876. )
  16877. as
  16878. begin
  16879.     declare @bytestr      nvarchar(10)
  16880.             ,@bitstr       nvarchar(10)
  16881.             ,@typed_null      nvarchar(255)
  16882.  
  16883.     --
  16884.     -- if @art_col is not NULL then it means one of the following:
  16885.     -- 1) If we are scripting for triggers - then it means the subscriber
  16886.     --     table (destination table) was altered and column id do not match
  16887.     --     relative column order(as specified in PK bitmap or columns_updated()).
  16888.     --    The @art_col will represent the relative column order in the bitmap
  16889.     --    and @this_col will represent the actual column id
  16890.     --
  16891.     -- 2) If we are scripting for synctran procedures on publisher - then 
  16892.     --    @art_col represents the relative index of the column that is being
  16893.     --    replicated and @this_col represents the actual column id of the column
  16894.     --
  16895.     -- if @art_col is NULL - then we will set it to the value of @this_col
  16896.     --
  16897.     if (@art_col is NULL)
  16898.         select @art_col = @this_col
  16899.         
  16900.     select @typed_null = case when (@coltype is null) then N'NULL'
  16901.                     else N'convert(' + @coltype + N', NULL)' end
  16902.  
  16903.     -- Optimization:
  16904.     -- If the column value is not needed, we set the corresponding
  16905.     -- param to null to reduce the network traffic. Here is the rule:
  16906.  
  16907.     -- For new values in update trigger,
  16908.     --    Set the param to column value or null depending on whether or
  16909.     --  or the column is updated.
  16910.     -- For old values 
  16911.     --    if ts col is replicated and the current column is not the ts col
  16912.     --    and the column is not in primary key, set the param to null
  16913.     -- For other cases
  16914.     --    set the param to column values.
  16915.  
  16916.     -- Called by proc
  16917.     if @type = 'pk_var'
  16918.     begin
  16919.         select @bytestr = convert( nvarchar, 1 + (@art_col-1) / 8 )
  16920.         select @bitstr =  convert( nvarchar, power(2, (@art_col-1) % 8 ) )
  16921.  
  16922.         select @column = N'case substring(@bitmap,' 
  16923.             + @bytestr + N',1) & ' + @bitstr +  
  16924.             N' when ' + @bitstr + N' then ' + N'@c'+ convert( nvarchar, @this_col ) + 
  16925.             N' else ' + N'@c'+ convert( nvarchar, @this_col )  + N'_old end'
  16926.     end
  16927.     else if (@from_proc = 1)
  16928.     begin
  16929.         select @bytestr = convert( nvarchar, 1 + (@art_col-1) / 8 )
  16930.         select @bitstr =  convert( nvarchar, power(2, (@art_col-1) % 8 ) )
  16931.  
  16932.         select @column = N'case substring(@bitmap,' 
  16933.             + @bytestr + N',1) & ' + @bitstr +  
  16934.             N' when ' + @bitstr + N' then ' + N'@c'+ convert( nvarchar, @this_col ) + 
  16935.             N' else [' + @colname + N'] end'
  16936.     end
  16937.     -- Called in trigger,
  16938.     else if (@is_new = 1) and (@op_type = 'upd')
  16939.     begin
  16940.         -- @bitmap is set using columns_updated() at the beginning
  16941.         -- of the trigger.
  16942.         select @bytestr = convert( nvarchar, 1 + (@art_col-1) / 8 )
  16943.         select @bitstr =  convert( nvarchar, power(2, (@art_col-1) % 8 ) )
  16944.         
  16945.         select @column = N'case substring(@bitmap,' + @bytestr + N',1) & ' + @bitstr +  
  16946.             N' when ' + @bitstr + N' then [' + @colname + N'] ' + 
  16947.             N' else ' + @typed_null 
  16948.             +' end'
  16949.     end
  16950.     else if ((@is_new = 0) and 
  16951.         (@ts_col is not null and @colname not in (@ts_col, N'msrepl_tran_version')) and
  16952.         (@primary_key_bitmap is not null and 
  16953.         (substring(@primary_key_bitmap, 1 + (@art_col-1) / 8 , 1) & power(2, (@art_col-1) % 8 )) = 0))
  16954.         select @column =  @typed_null
  16955.     else 
  16956.         select @column = N'[' + @colname  + N'] '
  16957.     
  16958.     -- Add a new line
  16959.     select @column = @column + N'
  16960.     '
  16961. end
  16962. go
  16963.  
  16964. --
  16965. -- Name: sp_addqueued_artinfo
  16966. --
  16967. -- Description: This procedure is invoked by distribution agent to populate MSsubscription_articles 
  16968. -- with all the necessary article meta data for queued publications. This article meta data is later 
  16969. -- used for conflict viewing (de-centralized). Invoked on subscriber.
  16970. --
  16971. -- Parameter: Refer to the comments in the create procedure statement
  16972. --
  16973. -- Returns: 1 or 0   0 = success
  16974. --
  16975. -- Security: Public procedure - does subscribe security check. 
  16976. --
  16977. raiserror('Creating procedure sp_addqueued_artinfo', 0,1)
  16978. go
  16979. CREATE PROCEDURE sp_addqueued_artinfo (
  16980.     @artid                int
  16981.     ,@article            sysname
  16982.     ,@publisher         sysname
  16983.     ,@publisher_db        sysname
  16984.     ,@publication        sysname
  16985.     ,@dest_table        sysname
  16986.     ,@owner                sysname
  16987.     ,@cft_table            sysname
  16988.     ,@columns            binary(32))
  16989. AS
  16990. BEGIN
  16991.     set nocount on
  16992.     declare     @agent_id int
  16993.                 ,@update_mode int
  16994.                 ,@retcode int
  16995.  
  16996.     --
  16997.     -- security check
  16998.     --
  16999.     exec @retcode = sp_MSreplcheck_subscribe
  17000.     if @@error <> 0 or @retcode <> 0
  17001.     begin
  17002.         return (1)
  17003.     end
  17004.     --
  17005.     -- Create system table MSsubscription_articles if it does not exist
  17006.     --
  17007.     IF NOT EXISTS (SELECT * FROM sysobjects WHERE 
  17008.         type = 'U' AND name = 'MSsubscription_articles')
  17009.     BEGIN
  17010.         CREATE TABLE dbo.MSsubscription_articles
  17011.         (
  17012.             agent_id        int NOT NULL,        -- related entry in MSsubscription_agents
  17013.             artid            int NOT NULL,        -- article id
  17014.             article            sysname,            -- article name
  17015.             dest_table        sysname,            -- destination table
  17016.             owner            sysname,
  17017.             cft_table        sysname,            -- conflict table
  17018.             columns            binary(32)
  17019.         )
  17020.         IF (@@ERROR != 0)
  17021.         begin
  17022.             raiserror('Debug:sp_addqueued_artinfo - create MSsubscription_articles failed', 16, 1)
  17023.             return (1)
  17024.         end
  17025.  
  17026.         CREATE UNIQUE CLUSTERED INDEX ucMSsubscription_articles ON dbo.MSsubscription_articles(agent_id, artid)
  17027.         IF (@@ERROR != 0)
  17028.         begin
  17029.             raiserror('Debug:sp_addqueued_artinfo - create index for MSsubscription_articles failed', 16, 1)
  17030.             return (1)
  17031.         end
  17032.         
  17033.         EXEC dbo.sp_MS_marksystemobject 'MSsubscription_articles'
  17034.     END
  17035.  
  17036.     --
  17037.     -- insert the row for the given article
  17038.     --
  17039.     select @agent_id = id, @update_mode = update_mode
  17040.     from MSsubscription_agents 
  17041.     where UPPER(publisher) = UPPER(@publisher) and 
  17042.         publisher_db = @publisher_db and 
  17043.         publication = @publication 
  17044.  
  17045.     if (@agent_id IS NULL)
  17046.     begin
  17047.         raiserror('Debug:sp_addqueued_artinfo - agent_id is null for [%s].[%s].[%s]', 
  17048.             16, 1, @publisher, @publisher_db, @publication)
  17049.         return (1)
  17050.     end
  17051.  
  17052.     -- If the subscription is read only or immediate, no need to article info.
  17053.     if @update_mode in (0,1)
  17054.         return 0
  17055.  
  17056.     --
  17057.     -- If MSMQ Queued mode - check if the subscriber is compliant for MSMQ 2.0
  17058.     --
  17059.     if (@update_mode in (2,3))
  17060.     begin
  17061.         if ((platform() & 0x1) != 0x1)
  17062.         begin
  17063.             --
  17064.             -- Win 9X platform
  17065.             --
  17066.             raiserror(21334, 16, 1, '2.0')
  17067.             return (1)
  17068.         end
  17069.  
  17070.         --
  17071.         -- Now we use xp_MSver to detect NT OS version
  17072.         -- MSMQ subscription only allowed for platforms that support MSMQ 2.0
  17073.         -- version 5.0.2195 or higher
  17074.         --
  17075.         create table #tosversion ( propid int, propname sysname collate database_default, value int, charvalue nvarchar(255) collate database_default)
  17076.         insert into #tosversion (propid, propname, value, charvalue)
  17077.             exec master.dbo.xp_msver N'WindowsVersion'
  17078.  
  17079.         declare @vervalue int
  17080.             ,@lobyte tinyint
  17081.             ,@hibyte tinyint
  17082.             ,@loword smallint
  17083.             ,@hiword smallint
  17084.  
  17085.         --
  17086.         -- low order byte of low order word = OSmajor, high order byte of low order word = OSminor
  17087.         -- high order word = OSbuild
  17088.         --
  17089.         select @vervalue = value from #tosversion where propname = N'WindowsVersion'
  17090.         select @loword = (@vervalue & 0xffff)
  17091.                 ,@hiword = (@vervalue / 0x10000) & 0xffff
  17092.         select @lobyte = @loword & 0xff
  17093.                 ,@hibyte = (@loword / 100) & 0xff
  17094.         drop table #tosversion
  17095.  
  17096.         --
  17097.         -- check for OS major version
  17098.         --
  17099.         if (@lobyte < 5)
  17100.         begin
  17101.             raiserror(21334, 16, 2, '2.0')
  17102.             return (1)
  17103.         end
  17104.  
  17105.         --
  17106.         -- check for OS build version
  17107.         --
  17108.         if (@lobyte = 5 and @hiword < 2195)
  17109.         begin
  17110.             raiserror(21334, 16, 3, '2.0')
  17111.             return (1)
  17112.         end
  17113.     end
  17114.  
  17115.     --
  17116.     -- Check for owner - use current user for NULL value
  17117.     --
  17118.     if (@owner IS NULL or lower(@owner) = N'null' collate database_default)
  17119.         select @owner = user_name()
  17120.  
  17121.     if exists (select * from MSsubscription_articles where agent_id = @agent_id and artid = @artid)
  17122.         delete MSsubscription_articles where agent_id = @agent_id and artid = @artid
  17123.         
  17124.     insert into MSsubscription_articles(agent_id, artid, article, dest_table, owner, cft_table, columns)
  17125.         values (@agent_id, @artid, @article, @dest_table, @owner, @cft_table, @columns)
  17126.  
  17127.     IF (@@ERROR != 0)
  17128.     begin
  17129.         raiserror('Debug:sp_addqueued_artinfo - insert failed', 16, 1)
  17130.         return (1)
  17131.     end
  17132.  
  17133.     --
  17134.     -- Do the queue initialization here
  17135.     -- this way we can initialize Snapshot/Logbased queued tran from one place
  17136.     --
  17137.     exec @retcode = dbo.sp_MSreset_queue @publisher, @publisher_db, @publication, @artid
  17138.     IF (@retcode != 0 or @@ERROR != 0)
  17139.     begin
  17140.         raiserror('Debug:sp_addqueued_artinfo - sp_MSreset_queue failed', 16, 1)
  17141.         return (1)
  17142.     end
  17143.     
  17144.     --
  17145.     -- all done
  17146.     --
  17147.     return 0    
  17148. END
  17149. go
  17150. exec dbo.sp_MS_marksystemobject sp_addqueued_artinfo
  17151. go
  17152.  
  17153. raiserror('Creating procedure sp_addsynctriggers', 0,1)
  17154. go
  17155.  
  17156. CREATE PROCEDURE sp_addsynctriggers (
  17157.     @sub_table       sysname,            -- table name 
  17158.     @sub_table_owner sysname,            -- table owner
  17159.     @publisher      sysname,            -- publishing server name
  17160.     @publisher_db   sysname,            -- publishing database name. If NULL then same as current db
  17161.     @publication    sysname,            -- publication name.
  17162.     @ins_proc       sysname,
  17163.     @upd_proc       sysname,
  17164.     @del_proc       sysname,
  17165.     @cftproc        sysname,
  17166.     @proc_owner        sysname,
  17167.     @identity_col   sysname = 'NULL', 
  17168.     @ts_col         sysname = 'NULL',
  17169.     @filter_clause  nvarchar(4000) = 'NULL',
  17170.     @primary_key_bitmap  varbinary(4000),
  17171.     @identity_support bit = 0,
  17172.     @independent_agent bit = 0
  17173.     ,@distributor    sysname                -- distribution server name
  17174.     ,@pubversion int = 1    -- 1 = when this call is generated by pre SP3 publishers, 2 = SP3 or later
  17175. )
  17176. AS
  17177. BEGIN
  17178.     set nocount on
  17179.  
  17180.     declare @db                        sysname
  17181.                 ,@trigname                sysname
  17182.                 ,@ins_trig                sysname
  17183.                 ,@upd_trig                sysname
  17184.                 ,@del_trig                sysname
  17185.                 ,@qual_ins_trig            nvarchar(540)
  17186.                 ,@qual_upd_trig            nvarchar(540)
  17187.                 ,@qual_del_trig            nvarchar(540)
  17188.                 ,@dbname                sysname
  17189.                 ,@ccols                    int
  17190.                 ,@cnt                    int
  17191.                 ,@retcode                int
  17192.                 ,@cmd                    nvarchar(4000)
  17193.                 ,@merge_pub_object_bit    int
  17194.                 ,@synctran_bit            int
  17195.                 ,@object_id                int
  17196.                 ,@bitmap_str                varchar(8000)
  17197.                 ,@constraint_name        sysname
  17198.                 ,@quoted_name            nvarchar(540)
  17199.                 ,@qualname                nvarchar(540)
  17200.                 ,@loctrancount             int
  17201.  
  17202.     select     @merge_pub_object_bit     = 128
  17203.                 ,@synctran_bit            = 256
  17204.  
  17205.     --  Security Check
  17206.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  17207.     IF @@ERROR <> 0 or @retcode <> 0
  17208.         RETURN(1)
  17209.     --
  17210.     -- validate @pubversion
  17211.     --
  17212.     if (@pubversion is null)
  17213.         select @pubversion = 1
  17214.     if (@pubversion not in (1,2))
  17215.         return 1
  17216.  
  17217.     -- Dist Agent executes this sproc with 'implicit transasctions on'.
  17218.     -- We take care of our own transactions boundaries to get out of tran 
  17219.     set implicit_transactions off
  17220.     select @loctrancount = @@trancount
  17221.     while @@trancount > 0 commit tran
  17222.  
  17223.     -- check valid server and database setting
  17224.     -- 1. nested trigger have to be on
  17225.     if exists (select * from master..sysconfigures where config = 115 and value = 0)
  17226.     begin
  17227.         raiserror(21081, 16, 1)
  17228.         return (1)
  17229.     end
  17230.  
  17231.     -- 2. db option: recursive trigger have to be off
  17232.     if DATABASEPROPERTY(db_name(), N'IsRecursiveTriggersEnabled') <> 0
  17233.     begin
  17234.         raiserror(21082, 16, 1)
  17235.         return (1)
  17236.     end    
  17237.     
  17238.     -- 2. db compatibility level have to be 7.0
  17239.     if exists (select * from master..sysdatabases where dbid = db_id() and 
  17240.     cmptlevel < 70)
  17241.     begin
  17242.         raiserror(21083, 16, 1)
  17243.         return (1)
  17244.     end    
  17245.  
  17246.     if lower(@sub_table_owner) = N'null'
  17247.         select @qualname = QUOTENAME(@sub_table)        
  17248.     else
  17249.         select @qualname = QUOTENAME(@sub_table_owner) + N'.' + QUOTENAME(@sub_table)
  17250.  
  17251.     -- Verify that table exists 
  17252.     select @object_id = object_id (@qualname)
  17253.     if @object_id is null
  17254.     begin
  17255.         raiserror(20507, 16, 1, @qualname, 'sp_addsynctriggers')
  17256.         return (1)
  17257.     end
  17258.  
  17259.     -- Add default to timestamp, identity and version guid column
  17260.     if OBJECTPROPERTY(@object_id, 'tablehastimestamp') <> 1
  17261.     begin
  17262.         select @constraint_name = 'MSrepl_synctran_ts_default_' + convert(nvarchar(10), @object_id)
  17263.         select @quoted_name = quotename(@ts_col)
  17264.         if @ts_col is not null and @ts_col not in ('null','NULL') and not exists
  17265.         (select * from sysobjects where name = @constraint_name)
  17266.         begin
  17267.             exec ('alter table ' + @qualname + 
  17268.                 ' add constraint ' + @constraint_name + 
  17269.                 ' default 0 for ' + @quoted_name )
  17270.             if @@ERROR<>0 return 1
  17271.         end
  17272.     end
  17273.     
  17274.     if OBJECTPROPERTY(@object_id, 'tablehasidentity') <> 1
  17275.     begin
  17276.         select @constraint_name = 'MSrepl_synctran_identity_default_' + convert(nvarchar(10), @object_id)
  17277.         select @quoted_name = quotename(@identity_col)
  17278.         if @identity_col is not null and @identity_col not in ('null','NULL') and not exists
  17279.             (select * from sysobjects where name = @constraint_name)
  17280.         begin
  17281.             exec ('alter table ' + @qualname + 
  17282.                 ' add constraint ' + @constraint_name + 
  17283.                 ' default 0 for ' + @quoted_name )
  17284.             if @@ERROR<>0 return 1
  17285.         end
  17286.     end
  17287.  
  17288.     -- The default constraint is transfered with snapshot already for native publication.
  17289.     -- Need to detect to see if default constraint already there.
  17290.     select @quoted_name = 'msrepl_tran_version'
  17291.     declare @colid int
  17292.     select @colid = colid from syscolumns where 
  17293.         id = @object_id and
  17294.         name = @quoted_name
  17295.     if not exists (select * from sysconstraints where
  17296.         id = @object_id and 
  17297.         colid = @colid and
  17298.         status & 5 = 5) -- default
  17299.     begin 
  17300.         select @constraint_name = 'MSrepl_tran_version_default_' + convert(nvarchar(10), @object_id)
  17301.         exec ('alter table ' + @qualname + 
  17302.             ' add constraint ' + @constraint_name + 
  17303.             ' default newid() for ' + @quoted_name )
  17304.         if @@ERROR<>0 return 1
  17305.     end
  17306.  
  17307.     --
  17308.     -- determine if we should pass @cftproc to scripting of synctran trigger
  17309.     -- Check if the subscription needs scripting for queued replication. 
  17310.     -- For publishers that are pre 80SP3 - cftproc should not be null
  17311.     -- that takes care of it. For publisher that 80SP3 or later - we need
  17312.     -- to validate the article information
  17313.     --
  17314.     -- Check the version of the publisher
  17315.     --
  17316.     if ((@pubversion = 2) and not (@cftproc is null or lower(@cftproc) = 'null'))
  17317.     begin
  17318.         --
  17319.         -- Publisher is 80SP3 or later
  17320.         -- @cftproc should exist and article information should exist
  17321.         -- for this subscription
  17322.         --
  17323.         if not exists (select artid 
  17324.             from (dbo.MSsubscription_articles as a join dbo.MSsubscription_agents as b
  17325.                     on a.agent_id = b.id)
  17326.             where b.publisher = UPPER(@publisher)
  17327.                 and b.publisher_db = @publisher_db
  17328.                 and b.publication = @publication
  17329.                 and a.dest_table = object_name(@object_id))
  17330.     begin
  17331.         --
  17332.         -- There is no article information
  17333.         -- disable queued specific scripting 
  17334.         --
  17335.         select @cftproc = 'null'
  17336.     end
  17337.     end
  17338.     
  17339.     -- If MSsubscription_properties table does not exists, create one.
  17340.     if (LOWER(@cftproc) = 'null')
  17341.     begin
  17342.         exec @retcode = dbo.sp_MScreate_sub_tables
  17343.             @tran_sub_table = 0,
  17344.             @property_table = 1,
  17345.             @sqlqueue_table = 0
  17346.     end
  17347.     else
  17348.     begin
  17349.         exec @retcode = dbo.sp_MScreate_sub_tables
  17350.             @tran_sub_table = 0,
  17351.             @property_table = 1,
  17352.             @sqlqueue_table = 1
  17353.     end
  17354.     IF @@ERROR <> 0 or @retcode <> 0
  17355.         RETURN(1)
  17356.  
  17357.     -- If no entry in MSsubscription_properties for this publication, add one.
  17358.     IF NOT EXISTS (select * from MSsubscription_properties 
  17359.             where UPPER(publisher) = UPPER(@publisher)
  17360.                 and publisher_db =  @publisher_db
  17361.                 and publication = @publication) 
  17362.     BEGIN
  17363.         -- Use status rpc for local publisher
  17364.         declare @security_mode int
  17365.         declare @login sysname
  17366.         if UPPER(@@servername) = UPPER(@publisher)
  17367.         begin
  17368.             select @security_mode = 2
  17369.         end
  17370.         else
  17371.         begin
  17372.             select @security_mode = 0
  17373.             select @login = 'sa'
  17374.         end
  17375.  
  17376.         exec @retcode = dbo.sp_link_publication
  17377.             @publisher = @publisher,
  17378.             @publisher_db = @publisher_db,
  17379.             @publication = @publication,
  17380.             @security_mode = @security_mode,
  17381.             @login = @login,
  17382.             @password = NULL,
  17383.             @distributor = @distributor
  17384.         IF @@ERROR <> 0 or @retcode <> 0
  17385.             RETURN(1)
  17386.     END
  17387.       
  17388.     if exists (select * from sysobjects where 
  17389.         replinfo & @merge_pub_object_bit <> 0 and
  17390.         id = @object_id)
  17391.     begin
  17392.         raiserror(21063, 16, 1, @qualname)
  17393.         return (1)
  17394.     end
  17395.     
  17396.     -- Get agent_id
  17397.     declare @agent_id int
  17398.  
  17399.     -- First try to get the agent id initialized by the distribution agent
  17400.     declare @login_time datetime
  17401.     select @login_time = login_time from master..sysprocesses where spid = @@spid
  17402.  
  17403.     select @agent_id = id from MSsubscription_agents where
  17404.         spid = @@spid and
  17405.         login_time = @login_time
  17406.  
  17407.     -- If row not found, the current call is not from a distribution agent. Uses
  17408.     -- are creating trigger manually using the script generated by
  17409.     -- sp_script_synctran_triggers.
  17410.     -- Get the row using the publication name. However, it is possible that there are
  17411.     -- more than one qualifed rows with different subscription_type, for example
  17412.     -- pull and push subscriptions to share agent publications or subscriptions that has
  17413.     -- not been cleaned up.
  17414.     if @agent_id is null
  17415.     begin
  17416.         declare @num_dup_rows int
  17417.         select @agent_id = avg(id), @num_dup_rows = count(*) from MSsubscription_agents where
  17418.             publisher = @publisher and
  17419.             publisher_db = @publisher_db and
  17420.             publication = case @independent_agent 
  17421.                 when 0 then N'ALL'
  17422.                 else @publication
  17423.                 end and
  17424.             -- We know the subscription must be updateble. This
  17425.             -- is to reduce the chance of dup rows.
  17426.             update_mode <> 0
  17427.  
  17428.         if @num_dup_rows > 1
  17429.         begin
  17430.             -- Raise subscription already exist error
  17431.             -- This should rarely happen.
  17432.             RAISERROR (14058, 16, -1)
  17433.             return(1)
  17434.         end
  17435.  
  17436.         if @agent_id is null
  17437.         begin
  17438.             raiserror(20588, 16, -1)
  17439.             return(1)
  17440.         end
  17441.     end
  17442.  
  17443.  
  17444.     /*
  17445.     **    Create system table MSreplication_objects if it does not exist
  17446.     */
  17447.     IF NOT EXISTS (SELECT * FROM sysobjects WHERE 
  17448.         type = 'U' AND name = 'MSreplication_objects')
  17449.         BEGIN
  17450.             CREATE TABLE dbo.MSreplication_objects
  17451.             (
  17452.             publisher sysname NULL,
  17453.             publisher_db sysname NULL,
  17454.                publication sysname NULL, 
  17455.             object_name    sysname NOT NULL,
  17456.             object_type    char(2) NOT NULL
  17457.             )
  17458.             IF @@ERROR <> 0
  17459.                 begin
  17460.                     rollback transaction 
  17461.                     return (1)
  17462.                 end
  17463.             
  17464.             CREATE UNIQUE CLUSTERED INDEX ucMSreplication_objects ON dbo.MSreplication_objects(object_name)
  17465.             EXEC dbo.sp_MS_marksystemobject 'dbo.MSreplication_objects'
  17466.         END
  17467.  
  17468.  
  17469.     -- Drop all replication triggers on the source object
  17470.     -- We should drop all because we don't support updatable subscriptions to 
  17471.     -- multiple publications on same dest table.
  17472.     declare object_cursor CURSOR LOCAL FAST_FORWARD for 
  17473.         select o.object_name, so.id from MSreplication_objects o, sysobjects so where
  17474.             o.object_name = so.name and
  17475.             so.parent_obj = @object_id and
  17476.             o.object_type = 'T'
  17477.  
  17478.     declare @old_id int 
  17479.     declare @old_name sysname
  17480.  
  17481.     OPEN object_cursor
  17482.     FETCH object_cursor INTO @old_name, @old_id
  17483.      WHILE (@@fetch_status <> -1)
  17484.     BEGIN
  17485.         -- Cleanup identity range table
  17486.         declare @parent_obj int
  17487.         select @parent_obj = 0
  17488.         select @parent_obj = parent_obj from sysobjects where id = @old_id
  17489.         if exists (select * from sysobjects where name = 'MSsub_identity_range')
  17490.             delete MSsub_identity_range where objid = @parent_obj
  17491.  
  17492.         -- Drop the trigger
  17493.         exec @retcode = dbo.sp_MSdrop_object 
  17494.             @object_id = @old_id
  17495.         if @retcode <> 0 or @@error <> 0
  17496.             goto UNDO
  17497.         delete from MSreplication_objects where object_name=@old_name
  17498.         FETCH object_cursor INTO @old_name, @old_id
  17499.     END
  17500.     CLOSE object_cursor
  17501.     DEALLOCATE object_cursor
  17502.  
  17503.     -- Generate trigger names
  17504.         select @trigname = RTRIM(SUBSTRING(@sub_table,1,110))
  17505.     select @ins_trig = N'trg_MSsync_ins_' + @trigname 
  17506.     select @upd_trig = N'trg_MSsync_upd_' + @trigname 
  17507.     select @del_trig = N'trg_MSsync_del_' + @trigname 
  17508.  
  17509.     -- check uniqueness of names and revert to ugly guid-based name if friendly name already exists
  17510.     if exists (select name from sysobjects where name in (@ins_trig, @upd_trig, @del_trig))
  17511.         begin
  17512.             declare @guid_name nvarchar(36)
  17513.             select @guid_name =  convert (nvarchar(36), newid())
  17514.         select @ins_trig = 'trg_MSsync_ins_' + @guid_name
  17515.         select @upd_trig = 'trg_MSsync_upd_' + @guid_name
  17516.         select @del_trig = 'trg_MSsync_del_' + @guid_name
  17517.         end
  17518.  
  17519.     -- Get qual names
  17520.     if lower(@sub_table_owner) = N'null'
  17521.     begin
  17522.         select @qual_ins_trig = @ins_trig
  17523.         select @qual_upd_trig = @upd_trig
  17524.         select @qual_del_trig = @del_trig
  17525.     end
  17526.     else
  17527.     begin
  17528.         select @qual_ins_trig = QUOTENAME(@sub_table_owner) + N'.' + @ins_trig
  17529.         select @qual_upd_trig = QUOTENAME(@sub_table_owner) + N'.' + @upd_trig
  17530.         select @qual_del_trig = QUOTENAME(@sub_table_owner) + N'.' + @del_trig
  17531.     end
  17532.  
  17533.     exec @retcode = master..xp_varbintohexstr @primary_key_bitmap, @bitmap_str output
  17534.     if @retcode <> 0 or @@error <> 0
  17535.         return 1
  17536.  
  17537. /*
  17538.     exec ('if exists (select * from sysobjects where name = N''' + @ins_trig + N''' and xtype = N''TR'')
  17539.         drop trigger ' + @ins_trig)
  17540.     exec ('if exists (select * from sysobjects where name = N''' + @upd_trig + N''' and xtype = N''TR'')
  17541.         drop trigger ' + @upd_trig)
  17542.     exec ('if exists (select * from sysobjects where name = N''' + @del_trig + N''' and xtype = N''TR'')
  17543.         drop trigger ' + @del_trig)
  17544.  
  17545. */
  17546.     -- We are now going to create triggers, so start a transaction
  17547.     begin tran
  17548.         -- Call out to individual create trigger routines
  17549.         select @dbname = db_name()
  17550.         select @cmd = 'sp_MSscript_sync_ins_trig ' + 
  17551.             convert( nvarchar, @object_id )  + ', N' + 
  17552.             quotename(@publisher, '''')     + ', N' + 
  17553.             quotename(@publisher_db, '''')  + ', N' + 
  17554.             quotename(@publication, '''')   + ', N' + 
  17555.             quotename(@ins_trig, '''')      + ', N' + 
  17556.             quotename(@ins_proc, '''')      + ', N' + 
  17557.             quotename(@proc_owner, '''')    + ', N' + 
  17558.             quotename(@cftproc, '''')       + ', ' + 
  17559.             convert(nvarchar(10), @agent_id) + ', N' + 
  17560.             quotename(@identity_col, '''') + ', N' + 
  17561.             quotename(@ts_col, '''')        
  17562.         if @filter_clause in ('NULL', 'null')
  17563.             select @cmd = @cmd + ', null' 
  17564.         else 
  17565.             select @cmd = @cmd + ', N''' + replace (@filter_clause,'''','''''')  + ''''
  17566.                                     
  17567.             -- Set primary key bitmap and pubversion
  17568.             select @cmd = @cmd + ', ' + @bitmap_str +  ', ' + cast(@pubversion as nvarchar(10))
  17569.  
  17570.         exec @retcode = master..xp_execresultset @cmd, @dbname
  17571.         IF @@ERROR <> 0 or @retcode <> 0
  17572.             goto UNDO
  17573.         select @cmd = 'sp_MSscript_sync_upd_trig ' + 
  17574.             convert( nvarchar, @object_id )  + ', N' + 
  17575.             quotename(@publisher, '''')     + ', N' + 
  17576.             quotename(@publisher_db, '''')  + ', N' + 
  17577.             quotename(@publication, '''')   + ', N' + 
  17578.             quotename(@upd_trig, '''')      + ', N' + 
  17579.             quotename(@upd_proc, '''')      + ', N' + 
  17580.             quotename(@proc_owner, '''')    + ', N' + 
  17581.             quotename(@cftproc, '''')       + ', ' + 
  17582.             convert(nvarchar(10), @agent_id)  + ', N' + 
  17583.             quotename(@identity_col, '''')  + ', N' + 
  17584.             quotename(@ts_col, '''')        
  17585.         if @filter_clause in ('NULL', 'null')
  17586.             select @cmd = @cmd + ', null' 
  17587.         else 
  17588.             select @cmd = @cmd + ', N''' + replace (@filter_clause,'''','''''')  + ''''
  17589.                                     
  17590.             -- Set primary key bitmap and pubversion
  17591.             select @cmd = @cmd + ', ' + @bitmap_str +  ', ' + cast(@pubversion as nvarchar(10))
  17592.  
  17593.         exec @retcode = master..xp_execresultset @cmd, @dbname
  17594.         IF @@ERROR <> 0 or @retcode <> 0
  17595.             goto UNDO
  17596.  
  17597.         select @cmd = 'sp_MSscript_sync_del_trig ' + 
  17598.             convert( nvarchar, @object_id )  + ', N' + 
  17599.             quotename(@publisher, '''')     + ', N' + 
  17600.             quotename(@publisher_db, '''')  + ', N' + 
  17601.             quotename(@publication, '''')   + ', N' + 
  17602.             quotename(@del_trig, '''')      + ', N' + 
  17603.             quotename(@del_proc, '''')      + ', N' + 
  17604.             quotename(@proc_owner, '''')    + ', N' + 
  17605.             quotename(@cftproc, '''')       + ', ' + 
  17606.             convert(nvarchar(10), @agent_id) + ', N' + 
  17607.             quotename(@identity_col, '''')  + ', N' + 
  17608.             quotename(@ts_col, '''')        
  17609.         if @filter_clause in ('NULL', 'null')
  17610.             select @cmd = @cmd + ', null' 
  17611.         else 
  17612.             select @cmd = @cmd + ', N''' + replace (@filter_clause,'''','''''')  + ''''            
  17613.  
  17614.             -- Set primary key bitmap and pubversion
  17615.             select @cmd = @cmd + ', ' + @bitmap_str +  ', ' + cast(@pubversion as nvarchar(10))
  17616.  
  17617.         exec @retcode = master..xp_execresultset @cmd, @dbname
  17618.         IF @@ERROR <> 0 or @retcode <> 0
  17619.             goto UNDO
  17620.  
  17621.         -- Drop old entries before insert. The triggers with those names
  17622.         -- are created as above.
  17623.         delete MSreplication_objects where object_name = @ins_trig
  17624.         IF @@ERROR <> 0
  17625.             goto UNDO
  17626.         delete MSreplication_objects where object_name = @upd_trig
  17627.         IF @@ERROR <> 0
  17628.             goto UNDO
  17629.         delete MSreplication_objects where object_name = @del_trig
  17630.         IF @@ERROR <> 0
  17631.             goto UNDO
  17632.  
  17633.         -- Mark procedures as system procs so they don't show up in the UI
  17634.         exec dbo.sp_MS_marksystemobject @qual_ins_trig
  17635.         IF @@ERROR <> 0
  17636.             goto UNDO
  17637.  
  17638.         insert into MSreplication_objects(publisher, publisher_db, publication, object_name, object_type)
  17639.                     values(@publisher, @publisher_db, @publication, @ins_trig, 'T')
  17640.         IF @@ERROR <> 0
  17641.             goto UNDO
  17642.  
  17643.         exec dbo.sp_MS_marksystemobject @qual_upd_trig
  17644.         IF @@ERROR <> 0
  17645.             goto UNDO
  17646.                 
  17647.         insert into MSreplication_objects(publisher, publisher_db, publication, object_name, object_type)
  17648.                     values(@publisher, @publisher_db, @publication, @upd_trig, 'T')
  17649.         IF @@ERROR <> 0
  17650.             goto UNDO
  17651.  
  17652.         exec dbo.sp_MS_marksystemobject @qual_del_trig
  17653.         IF @@ERROR <> 0
  17654.             goto UNDO
  17655.  
  17656.         insert into MSreplication_objects(publisher, publisher_db, publication, object_name, object_type)
  17657.                     values(@publisher, @publisher_db, @publication, @del_trig, 'T')
  17658.         IF @@ERROR <> 0
  17659.             goto UNDO
  17660.  
  17661.         -- Mark the table for warnings in BCP
  17662.         update sysobjects set replinfo = replinfo | @synctran_bit where
  17663.             id = @object_id
  17664.         IF @@ERROR <> 0
  17665.             goto UNDO
  17666.  
  17667.         -- Set up identity range table
  17668.         if @identity_support <> 0
  17669.         begin
  17670.             if not exists (select * from sysobjects where name = 'MSsub_identity_range')
  17671.             begin
  17672.                 create table dbo.MSsub_identity_range (
  17673.                     objid int not null,
  17674.                     range bigint not null,
  17675.                     last_seed bigint not null,
  17676.                     threshold int not null)
  17677.                 IF @@ERROR <> 0
  17678.                     goto UNDO
  17679.             
  17680.                 CREATE UNIQUE CLUSTERED INDEX ucMSsub_identity_range ON dbo.MSsub_identity_range (objid)
  17681.                 
  17682.                 EXEC dbo.sp_MS_marksystemobject 'MSsub_identity_range'
  17683.                 IF @@ERROR <> 0
  17684.                     goto UNDO
  17685.             end
  17686.             if not exists (select * from MSsub_identity_range where objid = @object_id)
  17687.             begin
  17688.                 -- add zero at the beginning.
  17689.                 insert into MSsub_identity_range (objid, range, last_seed, threshold) values
  17690.                     (@object_id, 0, 0, 0)
  17691.                 IF @@ERROR <> 0
  17692.                     goto UNDO
  17693.             end
  17694.         end
  17695.  
  17696.     -- commit tran
  17697.     commit tran
  17698.  
  17699.     -- Set trigger firing order for insert
  17700.     exec dbo.sp_settriggerorder @qual_ins_trig,'first','insert'
  17701.     exec dbo.sp_settriggerorder @qual_upd_trig,'first','update'
  17702.     exec dbo.sp_settriggerorder @qual_del_trig,'first','delete'
  17703.     
  17704.     -- Ignore errors.
  17705.     exec dbo.sp_MSsub_cleanup_orphans
  17706.  
  17707.     -- restore the trancount if necessary
  17708.     if (@loctrancount > 0)
  17709.     begin
  17710.         while (@@trancount < @loctrancount)
  17711.             begin tran
  17712.     end
  17713.  
  17714.     return (0)
  17715. UNDO:
  17716.     if @@trancount <> 0
  17717.         rollback tran
  17718.     return(1)
  17719. END
  17720. go
  17721.  
  17722. --
  17723. -- Name: sp_setreplfailovermode
  17724. --
  17725. -- Description: This SP is invoked on the subscriber to toggle the failover 
  17726. -- mode for immediate updating with failover to queued subscriptions.
  17727. --
  17728. -- Parameter: Refer to the comments in the create procedure statement
  17729. --
  17730. -- Returns: 1 or 0   0 = success
  17731. --
  17732. -- Security: Public procedure - does subscribe security check. 
  17733. --
  17734. raiserror('Creating procedure sp_setreplfailovermode', 0,1)
  17735. go
  17736. create procedure sp_setreplfailovermode (
  17737.     @publisher sysname,
  17738.     @publisher_db sysname,
  17739.     @publication sysname,
  17740.     @failover_mode nvarchar (10), 
  17741.     @override tinyint = 0)
  17742. as
  17743. begin
  17744.     set nocount on
  17745.     declare    @failover_mode_id tinyint, 
  17746.             @current_failover_mode_id bit,
  17747.             @retcode int,
  17748.             @queue_id sysname,
  17749.             @fqueue_empty int,
  17750.             @update_mode int,
  17751.             @queue_server sysname
  17752.  
  17753.     --
  17754.     -- security check
  17755.     --
  17756.     exec @retcode = sp_MSreplcheck_subscribe
  17757.     if @@error <> 0 or @retcode <> 0
  17758.     begin
  17759.         return (1)
  17760.     end
  17761.     --
  17762.     -- validate @failover_mode
  17763.     --
  17764.     if @failover_mode not in (N'immediate', N'sync', N'queued')
  17765.     begin
  17766.         raiserror (21184, 16, 1, '@failover_mode', 'immediate', 'sync', 'queued')
  17767.         return 1            
  17768.     end
  17769.     else
  17770.     begin
  17771.         if @failover_mode = 'immediate' or @failover_mode = 'sync'
  17772.             select @failover_mode_id = 0
  17773.         else if @failover_mode = 'queued'
  17774.             select @failover_mode_id = 1
  17775.     end
  17776.  
  17777.     --
  17778.     -- Only valid to get/set failover_mode, 
  17779.     -- if update_mode is failover (3,5)
  17780.     --
  17781.     select    @queue_id = queue_id, 
  17782.             @queue_server = queue_server,
  17783.             @current_failover_mode_id = failover_mode,
  17784.             @update_mode = update_mode
  17785.     from MSsubscription_agents
  17786.     where UPPER(publisher) = UPPER(@publisher) and 
  17787.         publisher_db = @publisher_db and
  17788.         publication = @publication and
  17789.         update_mode in (3,5)
  17790.  
  17791.     -- no such row exists
  17792.     if (@current_failover_mode_id is NULL)        
  17793.     begin
  17794.         raiserror (21185, 16, 1)
  17795.         return 1
  17796.     end
  17797.  
  17798.     -- should have a queue entry
  17799.     if (@queue_id is NULL)
  17800.     begin
  17801.         raiserror(21186, 16, 1, @publisher)
  17802.         return 1
  17803.     end
  17804.  
  17805.     --
  17806.     -- do the transition
  17807.     --
  17808.     if ((@current_failover_mode_id = 0 and @failover_mode_id = 0) or
  17809.             (@current_failover_mode_id = 1 and @failover_mode_id = 1))
  17810.     begin
  17811.         --
  17812.         -- Going from immediate to immediate, queued to queued is no-op
  17813.         --
  17814.         raiserror (21187, 16, 1)
  17815.     end
  17816.     else if (@current_failover_mode_id = 0 and @failover_mode_id = 1)
  17817.     begin
  17818.         --
  17819.         -- Going from immediate to queued : update MSsubscription_agents
  17820.         --
  17821.         update MSsubscription_agents
  17822.             set failover_mode = @failover_mode_id
  17823.             where UPPER(publisher) = UPPER(@publisher) and 
  17824.                 publisher_db = @publisher_db and
  17825.                 publication = @publication and
  17826.                 update_mode in (3,5)
  17827.  
  17828.         raiserror (21188, 10, 1, 'immediate', 'queued')
  17829.     end
  17830.     else if (@current_failover_mode_id = 1 and @failover_mode_id = 0)
  17831.     begin
  17832.         --
  17833.         -- Going from queued to immediate : if override is not set
  17834.         -- then check if the queue is empty and then allow if empty.
  17835.         -- If override is set, just update MSsubscription_agents
  17836.         --
  17837.         if (@override = 0)
  17838.         begin
  17839.             if (@update_mode = 3)
  17840.             begin
  17841.                 --
  17842.                 -- MSMQ processing
  17843.                 -- prefix the queue_id with queue server in direct format
  17844.                 -- and then perform peek in the queue
  17845.                 --
  17846.                 select @queue_id = N'DIRECT=OS:' + @queue_server + N'\PRIVATE$\' + @queue_id
  17847.                 
  17848.                 exec @retcode = master.dbo.xp_peekqueue @queue_id, @fqueue_empty output, 0
  17849.                 if (@@error != 0 or @retcode != 0)
  17850.                 begin
  17851.                     raiserror('sp_setreplfailovermode(debug): xp_peekqueue execution failed', 16, 1)
  17852.                     return 1
  17853.                 end
  17854.  
  17855.                 if (@fqueue_empty != 1)
  17856.                 begin
  17857.                     raiserror(21189, 16, 1, @queue_id)
  17858.                     return 1
  17859.                 end
  17860.             end
  17861.             else
  17862.             begin
  17863.                 --
  17864.                 -- SQL Queue processing
  17865.                 --
  17866.                 if exists (select * from MSreplication_queue 
  17867.                     where publisher = UPPER(@publisher) and 
  17868.                             publisher_db = @publisher_db and
  17869.                             publication = @publication )
  17870.                 begin
  17871.                     raiserror(21189, 16, 2, @queue_id)
  17872.                     return 1
  17873.                 end
  17874.             end
  17875.         end
  17876.         else
  17877.         begin
  17878.             raiserror(21190, 10, 1, 'queued', 'immediate')
  17879.         end
  17880.  
  17881.         --
  17882.         -- update MSsubscription_agents
  17883.         --
  17884.         update MSsubscription_agents
  17885.             set failover_mode = @failover_mode_id
  17886.             where publisher = @publisher and 
  17887.                 publisher_db = @publisher_db and
  17888.                 publication = @publication and
  17889.                 update_mode in (3,5)
  17890.  
  17891.         raiserror (21188, 10, 1, 'queued', 'immediate')
  17892.     end
  17893.  
  17894.     -- All done
  17895.     return 0
  17896. end
  17897. go
  17898. exec dbo.sp_MS_marksystemobject sp_setreplfailovermode
  17899. go
  17900.  
  17901. --
  17902. -- Name: sp_helpreplfailovermode
  17903. --
  17904. -- Description: This SP is used by Queued replication user and 
  17905. -- Replication UI to find out the failover state of a given queued subscription. 
  17906. -- Invoked on the subscriber
  17907. --
  17908. -- Parameter: Refer to the comments in the create procedure statement
  17909. --
  17910. -- Returns: 1 or 0   0 = success
  17911. --
  17912. -- Security: Public procedure - does subscribe security check. 
  17913. --
  17914. raiserror('Creating procedure sp_helpreplfailovermode', 0,1)
  17915. go
  17916. create procedure sp_helpreplfailovermode (
  17917.     @publisher sysname,
  17918.     @publisher_db sysname,
  17919.     @publication sysname,
  17920.     @failover_mode_id tinyint = 0 output,
  17921.     @failover_mode nvarchar(10) = NULL output)
  17922. as
  17923. BEGIN
  17924.     declare    @subfound bit
  17925.             ,@retcode int
  17926.  
  17927.     --
  17928.     -- security check
  17929.     --
  17930.     exec @retcode = sp_MSreplcheck_subscribe
  17931.     if @@error <> 0 or @retcode <> 0
  17932.     begin
  17933.         return (1)
  17934.     end
  17935.     --
  17936.     -- Check if the table MSsubscription_agents exists
  17937.     --
  17938.     if exists (select * from dbo.sysobjects 
  17939.                     where name = 'MSsubscription_agents')
  17940.     begin
  17941.         --
  17942.         -- Only valid to get failover_mode, if failover_mode is failover (3,5)
  17943.         --
  17944.         if exists (select * from dbo.MSsubscription_agents
  17945.                 where publisher = @publisher and 
  17946.                     publisher_db = @publisher_db and
  17947.                     publication = @publication and
  17948.                     update_mode in (3,5) )
  17949.             select @subfound = 1
  17950.         else
  17951.             select @subfound = 0
  17952.     end
  17953.     else
  17954.         select @subfound = 0
  17955.     
  17956.     --
  17957.     -- Did we find an entry for initialized failover subscription
  17958.     --
  17959.     if (@subfound = 0)
  17960.     begin
  17961.         --
  17962.         -- Three possibilities : uninitialized subscription, non existent subscription
  17963.         -- or a non-mixed mode. Check If we have a PULL uninitialized subscription
  17964.         --
  17965.         if exists (select * from dbo.sysobjects 
  17966.                         where name = 'MSreplication_subscriptions')
  17967.         begin
  17968.             if exists (select * from dbo.MSreplication_subscriptions
  17969.                             where publisher = @publisher and 
  17970.                                 publisher_db = @publisher_db and
  17971.                                 publication = @publication and
  17972.                                 update_mode in (3,5) )
  17973.             begin
  17974.                 --
  17975.                 -- unitialized PULL subscription : return the default values
  17976.                 --
  17977.                 select @failover_mode_id = 0
  17978.                 select @subfound = 1
  17979.             end
  17980.         end
  17981.  
  17982.         if (@subfound = 0)
  17983.         begin
  17984.             raiserror ('sp_helpreplfailovermode: Subscription for [%s].[%s].[%s] either has not been initialized or does not exist or does not support mixed mode',
  17985.                         16, 1, @publisher, @publisher_db, @publication)
  17986.             return 1
  17987.         end
  17988.     end
  17989.     else
  17990.     begin
  17991.         --
  17992.         -- we found our subscription
  17993.         --
  17994.         select @failover_mode_id = failover_mode
  17995.         from dbo.MSsubscription_agents
  17996.         where publisher = @publisher and 
  17997.             publisher_db = @publisher_db and
  17998.             publication = @publication and
  17999.             update_mode in (3,5) 
  18000.             
  18001.         --
  18002.         -- initialize to 'immediate' if necessary
  18003.         --
  18004.         if @failover_mode_id not in (0, 1)
  18005.         begin
  18006.             raiserror ('sp_helpreplfailovermode: invalid failover_mode value %d for [%s].[%s].[%s], setting to 0 [immediate]', 
  18007.                 11, 1, @failover_mode_id, @publisher, @publisher_db, @publication)
  18008.             update dbo.MSsubscription_agents 
  18009.             set failover_mode = 0
  18010.             where publisher = @publisher and 
  18011.                 publisher_db = @publisher_db and
  18012.                 publication = @publication and
  18013.                 update_mode in (3,5) 
  18014.  
  18015.             select @failover_mode_id = 0
  18016.         end
  18017.     end
  18018.  
  18019.     --
  18020.     -- prepare the output
  18021.     --
  18022.     select @failover_mode = case 
  18023.         when @failover_mode_id = 0 then N'immediate'
  18024.         when @failover_mode_id = 1 then N'queued'
  18025.         end
  18026.         
  18027.     select N'failover_mode value'  = @failover_mode_id, 
  18028.             N'failover_mode' = @failover_mode
  18029.  
  18030.     --
  18031.     -- all done
  18032.     --
  18033.     return 0
  18034. END
  18035. go
  18036. exec dbo.sp_MS_marksystemobject sp_helpreplfailovermode
  18037. go
  18038.  
  18039. raiserror('Creating procedure sp_helpreplicationdboption', 0,1)
  18040. go
  18041.  
  18042. CREATE PROCEDURE sp_helpreplicationdboption (
  18043.     @dbname sysname = '%', @type sysname = 'replication allowed'
  18044. )
  18045. AS
  18046. BEGIN
  18047.     SET NOCOUNT ON
  18048.  
  18049.     /*
  18050.     ** Declarations.
  18051.     */
  18052.  
  18053.     DECLARE @retcode int
  18054.             ,@typebit int
  18055.             ,@distbit int -- bit to distinguish distribution databases
  18056.             ,@dbowner bit
  18057.             ,@dbreadonly bit
  18058.             ,@replication_db sysname
  18059.  
  18060.     SELECT @distbit = 16
  18061.             ,@dbowner = 0
  18062.             ,@dbreadonly = 0
  18063.  
  18064.     -- don't do security check.
  18065.  
  18066.     if (lower(@type collate SQL_Latin1_General_CP1_CS_AS) like 'publish%')
  18067.         select @typebit = 1
  18068.     else if (lower(@type collate SQL_Latin1_General_CP1_CS_AS) like 'subscribe%')
  18069.         select @typebit = 2
  18070.     else if (lower(@type collate SQL_Latin1_General_CP1_CS_AS) like 'merge publish%')
  18071.         select @typebit = 4
  18072.     else if (lower(@type collate SQL_Latin1_General_CP1_CS_AS) like 'merge subscribe%')
  18073.         select @typebit = 8
  18074.     else if (lower(@type collate SQL_Latin1_General_CP1_CS_AS) like 'replication allowed%')
  18075.         select @typebit = 0
  18076.     else        
  18077.     begin
  18078.         raiserror(14091,-1,-1)
  18079.         return 1
  18080.     end
  18081.  
  18082.     /*
  18083.     ** Parameter Check:  @dbname.
  18084.     ** Check to make sure that the database name conforms to the rules
  18085.     ** for identifiers.
  18086.     */
  18087.  
  18088.     IF @dbname <> '%'
  18089.     BEGIN
  18090.         EXECUTE @retcode = dbo.sp_validname @dbname
  18091.         IF @@ERROR <> 0 OR @retcode <> 0
  18092.         RETURN (1)
  18093.     END
  18094.  
  18095.     /*
  18096.     ** Show databases with this option enabled.
  18097.     */
  18098.     CREATE TABLE #replicationdbs (name sysname collate database_default not null, id int identity NOT NULL, transpublish bit not null, mergepublish bit not null, dbowner bit not null, dbreadonly bit not null)
  18099.     if @typebit <> 0
  18100.     begin
  18101.         INSERT INTO #replicationdbs (name, transpublish, mergepublish, dbowner, dbreadonly)
  18102.             SELECT name, 
  18103.                 case when (category & 1) <> 0 then 1 else 0 end,
  18104.                 case when (category & 4) <> 0 then 1 else 0 end,
  18105.                 @dbowner,
  18106.                 DATABASEPROPERTY(name, N'IsReadOnly')
  18107.             FROM master.dbo.sysdatabases
  18108.             WHERE ((@dbname = N'%') OR (name = @dbname collate database_default))
  18109.                 AND (category & @typebit) <> 0 
  18110.                 AND (HAS_DBACCESS ( name ) = 1)
  18111.  
  18112.         DECLARE hCdboinfo CURSOR LOCAL FAST_FORWARD FOR
  18113.             SELECT name FROM #replicationdbs
  18114.             FOR READ ONLY
  18115.         OPEN hCdboinfo
  18116.         FETCH hCdboinfo INTO @replication_db
  18117.         WHILE (@@fetch_status <> -1)
  18118.         BEGIN
  18119.             EXEC @retcode = sp_MSrepl_isdbowner @replication_db
  18120.             IF (@retcode IS NOT NULL) AND (@retcode <> 0)
  18121.             BEGIN
  18122.                 UPDATE #replicationdbs set dbowner = 1 where name = @replication_db
  18123.             END
  18124.             FETCH hCdboinfo INTO @replication_db
  18125.         END
  18126.         CLOSE hCdboinfo
  18127.         DEALLOCATE hCdboinfo
  18128.     end            
  18129.     else
  18130.     begin
  18131.         DECLARE @db_category int
  18132.  
  18133.         /* Filter out distribution databases */
  18134.         DECLARE hC  CURSOR LOCAL FAST_FORWARD FOR 
  18135.             SELECT name, category, DATABASEPROPERTY(name, N'IsReadOnly')
  18136.             FROM master.dbo.sysdatabases 
  18137.             WHERE ((@dbname = N'%') OR (name = @dbname collate database_default)) 
  18138.                 AND (category & @distbit) = 0 
  18139.                 AND (HAS_DBACCESS ( name ) = 1)
  18140.             FOR READ ONLY
  18141.         OPEN hC
  18142.         FETCH hC INTO @replication_db, @db_category, @dbreadonly
  18143.         WHILE (@@fetch_status <> -1)
  18144.         BEGIN
  18145.             if @replication_db NOT IN ('master','model','tempdb','msdb','MSSQLWeb')
  18146.             BEGIN
  18147.                 EXEC @retcode = sp_MSrepl_isdbowner @replication_db
  18148.                 IF (@retcode IS NOT NULL) AND (@retcode <> 0)
  18149.                 BEGIN
  18150.                     SELECT @dbowner = 1
  18151.                 END
  18152.                 ELSE
  18153.                 BEGIN
  18154.                     SELECT @dbowner = 0
  18155.                 END
  18156.                 INSERT INTO #replicationdbs (name, transpublish, mergepublish, dbowner, dbreadonly) 
  18157.                 VALUES (@replication_db,
  18158.                         case when (@db_category & 1) <> 0 then 1 else 0 end,
  18159.                         case when (@db_category & 4) <> 0 then 1 else 0 end,
  18160.                         @dbowner, @dbreadonly)
  18161.             END
  18162.             FETCH hC INTO @replication_db, @db_category, @dbreadonly
  18163.         END
  18164.         CLOSE hC
  18165.         DEALLOCATE hC
  18166.     end
  18167.     SELECT * FROM #replicationdbs
  18168.     -- DROP TABLE #replicationdbs
  18169. END
  18170. go
  18171.  
  18172. raiserror('Creating procedure sp_MScheck_agent_instance', 0,1)
  18173. GO
  18174. CREATE PROCEDURE sp_MScheck_agent_instance
  18175. @application_name sysname,
  18176. @agent_type int = NULL
  18177.  
  18178. as
  18179.     declare @count_pro int
  18180.     set nocount on
  18181.     select @count_pro = count(*) from master..sysprocesses where 
  18182.         program_name = @application_name collate database_default
  18183.     -- type 3 is for 7.0 distribution agent backward compatibility.
  18184.     if @agent_type = 3
  18185.     begin
  18186.         -- The distribution agent will before connecting to the publisher with unique 
  18187.         -- application name
  18188.         if @count_pro > 0
  18189.             raiserror (21036, 16, -1, 'distribution')
  18190.     end
  18191.     -- 10 is 7.5 version of the distribution agent.
  18192.     else if @agent_type = 10
  18193.     begin
  18194.         -- The distribution agent will connecting to the publisher with unique 
  18195.         -- application name and then check.
  18196.         if @count_pro > 1
  18197.             raiserror (21036, 16, -1, 'distribution')
  18198.     end
  18199.     else if @agent_type = 4
  18200.     begin
  18201.         -- The merge agent will connect to the publisher with unique application name
  18202.         -- then call this procedure
  18203.         if @count_pro > 1 
  18204.             raiserror (21036, 16, -1, 'merge')
  18205.     end
  18206.     else if @agent_type = 1
  18207.     begin
  18208.         -- The snapshot agent will connect to the distributiondb with unique application name
  18209.         -- then call this procedure
  18210.         if @count_pro > 2 
  18211.             raiserror (21036, 16, -1, 'snapshot')
  18212.     end
  18213.     else if @agent_type = 2
  18214.     begin
  18215.         -- The logreader agent will connect to the distributiondb with unique application name
  18216.         -- then call this procedure
  18217.         if @count_pro > 1 
  18218.             raiserror (21036, 16, -1, 'logreader')
  18219.     end
  18220.     else if @agent_type = 9
  18221.     begin
  18222.         -- The queuereader agent will connect to the distributiondb with unique application name
  18223.         -- then call this procedure
  18224.         if @count_pro > 1 
  18225.             raiserror (21036, 16, -1, 'queuereader')
  18226.     end
  18227. go
  18228.  
  18229. CREATE PROCEDURE sp_MSBumpupCompLevel(
  18230. @pubid                uniqueidentifier,
  18231. @new_level            int
  18232. )
  18233. as
  18234.  
  18235. declare @retcode int
  18236. /*
  18237. ** Security Check
  18238. */
  18239.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  18240.     IF @@ERROR <> 0 or @retcode <> 0
  18241.         return (1)
  18242.  
  18243.     /* always bump UP, not Down in any case */
  18244.     update sysmergepublications set backward_comp_level = @new_level where pubid=@pubid and backward_comp_level < @new_level
  18245.     if @@ERROR<>0
  18246.         return (1)
  18247.     return (0)
  18248. GO
  18249. exec dbo.sp_MS_marksystemobject sp_MSBumpupCompLevel
  18250. go
  18251.  
  18252.  
  18253. CREATE PROCEDURE sp_MSCleanupForPullReinit (
  18254.     @publication         sysname,
  18255.     @publisher_db        sysname,
  18256.     @publisher             sysname = @@servername
  18257.     ) AS
  18258.     declare @pubid         uniqueidentifier
  18259.     declare @artid         uniqueidentifier
  18260.     declare @retcode    smallint
  18261.  
  18262.     /*
  18263.     ** Security Check
  18264.     */
  18265.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  18266.     IF @@ERROR <> 0 or @retcode <> 0
  18267.         return (1)
  18268.  
  18269.     /* This only gets called after database is enable to subscribe, so sysmergepublications should exist */
  18270.     select @pubid = pubid FROM sysmergepublications 
  18271.         WHERE name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db = @publisher_db
  18272.  
  18273.     /* Normal case - nothing to cleanup, just return */
  18274.     if @pubid is null
  18275.         return (1)    
  18276.  
  18277.     begin transaction
  18278.     save tran cleanupforreinit
  18279.     /* 
  18280.     ** Make sure you NULL out gen_cur for other articles that share this table 
  18281.     ** since we are deleting the genhistroy row for that generation 
  18282.     */
  18283.     update sysmergearticles set gen_cur=NULL where gen_cur in
  18284.         (select generation from MSmerge_genhistory where pubid = @pubid)
  18285.     if @@ERROR<>0 
  18286.         goto Error
  18287.     delete from MSmerge_genhistory where pubid = @pubid
  18288.     if @@ERROR<>0 
  18289.         goto Error
  18290.     delete from sysmergesubsetfilters where pubid=@pubid
  18291.     if @@ERROR<>0 
  18292.         goto Error
  18293.     delete from sysmergeschemachange where pubid = @pubid
  18294.     if @@ERROR<>0 
  18295.         goto Error
  18296.     delete from MSmerge_contents where tablenick in (select nickname from sysmergearticles where pubid=@pubid)
  18297.     if @@ERROR<>0 
  18298.         goto Error
  18299.     delete from MSmerge_tombstone where tablenick in (select nickname from sysmergearticles where pubid=@pubid)
  18300.     if @@ERROR<>0 
  18301.         goto Error
  18302.     update MSmerge_replinfo set recgen = NULL, recguid = NULL, sentgen = NULL, sentguid = NULL 
  18303.             where repid in ( select subid from sysmergesubscriptions where pubid = @pubid)
  18304.     if @@ERROR<>0 
  18305.         goto Error
  18306.  
  18307.     commit tran 
  18308.     return (0)
  18309.  
  18310. Error:
  18311.     rollback tran cleanupforreinit
  18312.     commit tran 
  18313.     return (1)
  18314. GO
  18315. exec dbo.sp_MS_marksystemobject sp_MSCleanupForPullReinit
  18316. go
  18317.  
  18318. grant execute on dbo.sp_MSCleanupForPullReinit to public
  18319. go
  18320.  
  18321.  
  18322. raiserror('Creating procedure sp_MSpublicationcleanup', 0,1)
  18323. GO
  18324.  
  18325. CREATE PROCEDURE sp_MSpublicationcleanup (
  18326.     @publication         sysname,
  18327.     @publisher_db        sysname,
  18328.     @publisher               sysname = @@servername
  18329.     ) AS
  18330.     declare @pubid         uniqueidentifier
  18331.     declare @artid         uniqueidentifier
  18332.     declare @retcode    smallint
  18333.     declare @objectname sysname
  18334.     declare @objectowner sysname
  18335.  
  18336.     /*
  18337.     ** Security Check
  18338.     */
  18339.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  18340.     IF @@ERROR <> 0 or @retcode <> 0
  18341.         return (1)
  18342.  
  18343.     /* This only gets called after database is enable to subscribe, so sysmergepublications should exist */
  18344.     select @pubid = pubid FROM sysmergepublications 
  18345.         WHERE name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db = @publisher_db
  18346.  
  18347.     /* Normal case - nothing to cleanup, just return */
  18348.     if @pubid is null
  18349.         return (1)
  18350.  
  18351.     /* 
  18352.     ** If we are deleting the last publication in the database, ie there are articles in
  18353.     ** sysmergearticles with a different pubid then the one being dropped
  18354.     ** then remove all the rows in MSmerge_genhistory, MSmerge_contents and MSmerge_tombstone 
  18355.     ** use a truncate table in order to make the operation non logged and hence efficient
  18356.     */
  18357.     if not exists (select * from sysmergearticles where pubid <> @pubid)
  18358.         begin
  18359.             truncate table MSmerge_genhistory
  18360.             truncate table MSmerge_contents
  18361.             truncate table MSmerge_tombstone
  18362.         end
  18363.  
  18364.     begin transaction
  18365.     save tran MSpublicationcleanup
  18366.     /* Clean up the articles for this publication, and delete the row */
  18367.     select @artid = artid FROM sysmergearticles WHERE pubid = @pubid
  18368.     while @artid is not null
  18369.         begin
  18370.         if not exists (select * from sysmergearticles WHERE artid = @artid and pubid <> @pubid)
  18371.             begin
  18372.                 exec @retcode=sp_MSarticlecleanup @pubid, @artid
  18373.                 if @retcode<>0 or @@ERROR<>0 
  18374.                     goto Error
  18375.             end
  18376.         delete from sysmergearticles where artid = @artid and pubid = @pubid
  18377.         if @@ERROR<>0 
  18378.             goto Error
  18379.         set @artid = NULL
  18380.         select @artid = artid FROM sysmergearticles WHERE pubid = @pubid
  18381.         end
  18382.         
  18383.     /* Unmark all schema articles in this publication */
  18384.     if exists (select * from sysobjects where name = 'sysmergeschemaarticles')
  18385.     begin
  18386.         declare hschemaarticle_cur cursor local fast_forward for
  18387.             select destination_object, destination_owner from sysmergeschemaarticles where
  18388.             pubid = @pubid 
  18389.         for read only
  18390.         open hschemaarticle_cur
  18391.         fetch hschemaarticle_cur into @objectname, @objectowner
  18392.         while (@@fetch_status<>-1)
  18393.         begin
  18394.                 exec  sp_MSunmarkschemaobject @objectname, @objectowner    
  18395.                 if @retcode<>0 or @@ERROR<>0 
  18396.                     goto Error
  18397.                 fetch hschemaarticle_cur into @objectname, @objectowner
  18398.         end
  18399.         close hschemaarticle_cur
  18400.         deallocate hschemaarticle_cur
  18401.  
  18402.         /* Delete all schema article rows for this publication*/
  18403.         delete from sysmergeschemaarticles where pubid = @pubid
  18404.         if @@ERROR<>0 
  18405.             goto Error
  18406.     end
  18407.     
  18408.     /* Now clean up any traces in other system tables */
  18409.  
  18410.     /* 
  18411.     ** Make sure you NULL out gen_cur for other articles that share this table 
  18412.     ** since we are deleting the genhistroy row for that generation 
  18413.     */
  18414.     update sysmergearticles set gen_cur=NULL where gen_cur in
  18415.         (select generation from MSmerge_genhistory where pubid = @pubid)
  18416.     if @@ERROR<>0 
  18417.         goto Error
  18418.     delete from MSmerge_genhistory where pubid = @pubid
  18419.     if @@ERROR<>0 
  18420.         goto Error
  18421.     delete from MSmerge_replinfo where repid in (select subid from sysmergesubscriptions where pubid = @pubid and status <> 2)
  18422.     if @@ERROR<>0 
  18423.         goto Error
  18424.     delete from sysmergesubsetfilters where pubid = @pubid
  18425.     if @@ERROR<>0 
  18426.         goto Error
  18427.     delete from sysmergesubscriptions where pubid = @pubid and status <> 2
  18428.     if @@ERROR<>0 
  18429.         goto Error
  18430.     delete from sysmergepublications where pubid = @pubid
  18431.     if @@ERROR<>0 
  18432.         goto Error
  18433.     delete from sysmergeschemachange where pubid = @pubid
  18434.     if @@ERROR<>0 
  18435.         goto Error
  18436.  
  18437.     commit tran 
  18438.     
  18439.     return (0)
  18440.  
  18441. Error:
  18442.     rollback tran MSpublicationcleanup
  18443.     commit tran 
  18444.     return (1)
  18445. GO
  18446. exec dbo.sp_MS_marksystemobject sp_MSpublicationcleanup
  18447. go
  18448.  
  18449. grant execute on dbo.sp_MSpublicationcleanup to public
  18450. go
  18451.  
  18452. raiserror('Creating procedure sp_removedbreplication', 0,1)
  18453. GO
  18454.  
  18455. create procedure sp_cleanupdbreplication
  18456. AS
  18457. set nocount on
  18458.  
  18459. declare @pubid            uniqueidentifier
  18460. declare @artid            uniqueidentifier
  18461. declare @retcode        int
  18462.  
  18463. exec @retcode = sp_MSreplcheck_publish
  18464. if (@retcode <> 0 or @@error <> 0)
  18465.     return 1
  18466.     
  18467. if not exists (select name from sysobjects where name='sysmergesubscriptions')
  18468.     return (0)
  18469. declare #RemoveReplication CURSOR LOCAL FAST_FORWARD for 
  18470.     select pubid from sysmergepublications 
  18471. open #RemoveReplication
  18472. fetch #RemoveReplication into @pubid
  18473. while (@@fetch_status<>-1)
  18474. begin
  18475.     /* Clean up the articles for this publication, and delete the row */
  18476.     select @artid = artid FROM sysmergearticles WHERE pubid = @pubid
  18477.     while @artid is not null
  18478.         begin
  18479.         if not exists (select * from sysmergearticles WHERE artid = @artid and pubid <> @pubid)
  18480.             begin
  18481.                 exec @retcode=sp_MSarticlecleanup @pubid, @artid
  18482.                 if @retcode<>0 or @@ERROR<>0 
  18483.                 begin
  18484.                     close #RemoveReplication
  18485.                     deallocate #RemoveReplication
  18486.                     return (1)
  18487.                 end
  18488.             end
  18489.         delete from sysmergearticles where artid = @artid and pubid = @pubid
  18490.         set @artid = NULL
  18491.         select @artid = artid FROM sysmergearticles WHERE pubid = @pubid
  18492.         end
  18493.     fetch #RemoveReplication into @pubid
  18494. end
  18495. close #RemoveReplication
  18496. deallocate #RemoveReplication
  18497.         
  18498. /* Now clean up any traces in other system tables */
  18499.     
  18500. delete from MSmerge_genhistory 
  18501. delete from MSmerge_replinfo
  18502. delete from sysmergesubsetfilters 
  18503. delete from sysmergesubscriptions 
  18504. delete from sysmergepublications
  18505. delete from sysmergeschemachange
  18506. return (0)
  18507.  
  18508. GO
  18509. exec dbo.sp_MS_marksystemobject sp_cleanupdbreplication
  18510. go
  18511.  
  18512. grant execute on dbo.sp_cleanupdbreplication to public
  18513. go
  18514.  
  18515.  
  18516.  
  18517.  
  18518. raiserror('Creating procedure sp_MSarticlecleanup', 0,1)
  18519. GO
  18520.  
  18521. create procedure sp_MSarticlecleanup
  18522.     (@pubid uniqueidentifier, @artid uniqueidentifier)
  18523. as
  18524.     set nocount on
  18525.     declare @source_table     nvarchar(270)
  18526.     declare @conflict_table nvarchar(270)
  18527.     declare @ownername         sysname
  18528.     declare @objectname     sysname
  18529.     declare @tablenick        int
  18530.     declare @objid             int
  18531.     declare @sync_objid     int
  18532.     declare @view_type        int
  18533.     declare @tsview            nvarchar(50)
  18534.     declare @guidstr        nvarchar(50)
  18535.     declare @csview            nvarchar(50)
  18536.     declare @viewname        nvarchar(270)
  18537.     declare @retcode        smallint
  18538.     declare @qualified_name    nvarchar(270)
  18539.     declare @bi_tablename    sysname
  18540.     declare    @bi_viewname    sysname
  18541.     declare @bi_procname    sysname
  18542.     declare @constraintname    sysname
  18543.     declare @merge_pub_markcolumn_bit int
  18544.     declare @merge_pub_unmarkcolumn_bit int
  18545.     declare @bitableview sysname
  18546.     
  18547.     -- to be called after article is set up in a subscriber
  18548.  
  18549.     /*
  18550.     ** Security Check
  18551.     */
  18552.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  18553.     IF @@ERROR <> 0 or @retcode <> 0
  18554.         return (1)
  18555.  
  18556.     select @merge_pub_markcolumn_bit = 0x4000
  18557.     select @merge_pub_unmarkcolumn_bit = ~@merge_pub_markcolumn_bit
  18558.  
  18559.     select @objid = max(objid) from sysmergearticles where artid = @artid
  18560.  
  18561.     -- get owner name, and table name
  18562.     select @objectname = name, @ownername = user_name(uid)
  18563.         from sysobjects    where id = @objid
  18564.  
  18565.     -- construct the qualified table name
  18566.     select @source_table = QUOTENAME(@ownername) + '.' + QUOTENAME(@objectname)
  18567.  
  18568.     exec @retcode=sp_MSguidtostr @artid, @guidstr out
  18569.     if @retcode<>0 or @@ERROR<>0 return (1)
  18570.     
  18571.     -- get the insert, update and conflict proc names from sysmergearticles
  18572.     select     @sync_objid = sync_objid, 
  18573.             @view_type = view_type, 
  18574.             @tablenick = nickname,
  18575.             @bi_tablename = object_name(before_image_objid),
  18576.             @bi_viewname = object_name(before_view_objid),
  18577.             @conflict_table = conflict_table 
  18578.         from sysmergearticles where
  18579.             pubid = @pubid and artid = @artid
  18580.  
  18581.     /*
  18582.     ** We are not owner_qualifed this conflict table because it is created by snapshot agent
  18583.     */
  18584.     select @qualified_name = QUOTENAME(@ownername) + '.' + QUOTENAME(@conflict_table)
  18585.  
  18586.     /* Drop the conflict table */
  18587.     if (@conflict_table IS NOT NULL) and exists (select * from sysobjects where
  18588.             name = @conflict_table and type = 'U')
  18589.         begin
  18590.             exec ('drop table ' + @qualified_name)
  18591.             if @@ERROR<>0 return (1)
  18592.         end
  18593.  
  18594.  
  18595.     /* If there is a before image table, drop it and its cleanup proc */
  18596.     if (@bi_tablename is not null)
  18597.         begin
  18598.         set @bi_procname = @bi_tablename + '_clean'
  18599.  
  18600.         if exists (select * from sysobjects where
  18601.             name = @bi_procname and type = 'P')
  18602.             begin
  18603.             exec ('drop proc ' + @bi_procname)
  18604.             if @@ERROR<>0 return (1)
  18605.             end
  18606.         exec ('drop table ' + @bi_tablename)
  18607.         if @@ERROR<>0 return (1)
  18608.         end
  18609.     /* If there is a before image view, drop it */
  18610.     if (@bi_viewname is not null)
  18611.         begin
  18612.         exec ('drop view ' + @bi_viewname)
  18613.         if @@ERROR<>0 return (1)
  18614.         end
  18615.         
  18616.     /* Drop the article procs */
  18617.     exec @retcode=sp_MSdroparticleprocs @pubid, @artid
  18618.     if @@ERROR<>0 or @retcode<>0 return (1)
  18619.  
  18620.     /* Drop the article triggers */
  18621.     exec @retcode=sp_MSdroparticletriggers @source_table
  18622.     if @@ERROR<>0 or @retcode<>0 return (1)
  18623.  
  18624.     exec @retcode=sp_MSunmarkreplinfo @objectname, @ownername
  18625.     if @@ERROR<>0 or @retcode<>0 return (1)
  18626.  
  18627.     /* so that columns can be dropped */
  18628.     update syscolumns set colstat=colstat & @merge_pub_unmarkcolumn_bit where id=@objid
  18629.     if @@ERROR<>0 return (1)
  18630.  
  18631.     /* If the article's has a temporary ( view type = 2) or a permanent view (view_type = 1 ) drop the sync object */
  18632.     if (@view_type = 1 OR @view_type = 2)
  18633.         begin
  18634.             select @viewname = sysobjects.name from sysobjects where 
  18635.                 ObjectProperty (sysobjects.id, 'IsView') = 1 
  18636.                 and ObjectProperty (sysobjects.id, 'IsMSShipped') = 1 
  18637.                 and sysobjects.id = @sync_objid
  18638.             if @viewname IS NOT NULL
  18639.                 begin
  18640.                     select @ownername = user_name(uid) from sysobjects where name=@viewname
  18641.                     set @viewname = QUOTENAME(@ownername) + '.' + QUOTENAME(@viewname)
  18642.                     exec ('drop view ' + @viewname)
  18643.                     if @@ERROR<>0 return (1)
  18644.                 end
  18645.         end
  18646.  
  18647.     /*
  18648.     ** Drop the views created for MSmerge_contents, MSmerge_tombstone and sysmergearticles before dropping these two tables
  18649.     */
  18650.     set @csview = 'ctsv_' + @guidstr
  18651.     set @tsview = 'tsvw_' + @guidstr
  18652.     set @bitableview = 'MSbivw_' + @guidstr
  18653.  
  18654.     if EXISTS (select * from sysobjects where name=@csview and type='V')
  18655.     BEGIN
  18656.         select @ownername = user_name(uid) from sysobjects where  name=@csview
  18657.         select @viewname = QUOTENAME(@ownername) + '.' + QUOTENAME(@csview)
  18658.         exec ('drop view ' + @viewname)
  18659.             if @@ERROR<>0 return (1)
  18660.     END
  18661.         
  18662.     if EXISTS (select * from sysobjects where name=@tsview and type='V')
  18663.     BEGIN
  18664.         select @ownername = user_name(uid) from sysobjects where  name=@tsview
  18665.         select @viewname = QUOTENAME(@ownername) + '.' + QUOTENAME(@tsview)
  18666.         exec ('drop view ' + @viewname)
  18667.             if @@ERROR<>0 return (1)
  18668.     END
  18669.     
  18670.     if EXISTS (select * from sysobjects where name=@bitableview and type='V')
  18671.     BEGIN
  18672.         select @ownername = user_name(uid) from sysobjects where  name=@bitableview
  18673.         select @viewname = QUOTENAME(@ownername) + '.' + QUOTENAME(@bitableview)
  18674.         exec ('drop view ' + @viewname)
  18675.             if @@ERROR<>0 return (1)
  18676.     END
  18677.  
  18678.     select @constraintname = 'repl_identity_range_pub_' + convert(nvarchar(36), @artid)
  18679.     select @constraintname = REPLACE(@constraintname, '-', '_')
  18680.     if exists (select * from sysobjects where name = @constraintname and xtype='C')
  18681.     begin
  18682.         exec ('alter table '+ @source_table + ' drop constraint ' + @constraintname)
  18683.         if @@ERROR<>0
  18684.             return (1)
  18685.     end
  18686.  
  18687.     select @constraintname = 'repl_identity_range_repub_' + convert(nvarchar(36), @artid)
  18688.     select @constraintname = REPLACE(@constraintname, '-', '_')
  18689.     if exists (select * from sysobjects where name = @constraintname and xtype='C')
  18690.     begin
  18691.         exec ('alter table '+ @source_table + ' drop constraint ' + @constraintname)
  18692.         if @@ERROR<>0
  18693.             return (1)
  18694.     end
  18695.  
  18696.     /* Delete from contents, tombstone, delete conflicts; Ignore errors that occur */
  18697.     delete from MSmerge_contents where tablenick = @tablenick
  18698.     delete from MSmerge_tombstone where tablenick = @tablenick
  18699.     /* Delete rows from MSmerge_genhistory - if this is the last table that refers to them */
  18700.     if not exists (select * from sysmergearticles where nickname = @tablenick and pubid <> @pubid)
  18701.         delete from MSmerge_genhistory where art_nick = @tablenick
  18702.  
  18703.     delete from MSmerge_delete_conflicts where tablenick = @tablenick
  18704.     delete from MSrepl_identity_range where objid=@objid
  18705. GO
  18706.  
  18707. exec dbo.sp_MS_marksystemobject sp_MSarticlecleanup
  18708. go
  18709.  
  18710. grant execute on dbo.sp_MSarticlecleanup to public
  18711. go
  18712.  
  18713. raiserror('Creating procedure sp_MSdroparticleprocs', 0,1)
  18714. GO
  18715.  
  18716. create procedure sp_MSdroparticleprocs
  18717.     (@pubid uniqueidentifier, @artid uniqueidentifier)
  18718. as
  18719.     set nocount on
  18720.     declare @ins_procname     sysname
  18721.     declare @upd_procname     sysname
  18722.     declare @conf_procname     sysname
  18723.     declare @sel_procname    sysname
  18724.     declare @tmp_procname    nvarchar(260)
  18725.     declare @view_sel_proc     nvarchar(290)
  18726.     declare @owner            sysname
  18727.     declare @objid            int
  18728.     
  18729.     -- get the insert, update and conflict proc names from sysmergearticles
  18730.     select @ins_procname = insert_proc,    
  18731.             @upd_procname = update_proc, 
  18732.             @sel_procname = select_proc,
  18733.             @conf_procname = ins_conflict_proc,
  18734.             @view_sel_proc = view_sel_proc,
  18735.             @objid = objid
  18736.         from sysmergearticles where
  18737.             pubid = @pubid and artid = @artid
  18738.  
  18739.     if (@ins_procname IS NOT NULL) and exists (select * from sysobjects where
  18740.             name = @ins_procname and type = 'P')
  18741.         begin
  18742.             select @owner = user_name(uid) from sysobjects where name=@ins_procname
  18743.             select @tmp_procname = QUOTENAME(@owner) + '.' + QUOTENAME(@ins_procname)
  18744.             exec ('drop proc ' + @tmp_procname)
  18745.             if @@ERROR<>0 return (1)
  18746.             update sysmergearticles set insert_proc = NULL where pubid=@pubid and artid=@artid
  18747.         end
  18748.     if (@upd_procname IS NOT NULL) and exists (select * from sysobjects where
  18749.             name = @upd_procname and type = 'P')
  18750.         begin
  18751.             select @owner = user_name(uid) from sysobjects where name=@upd_procname
  18752.             select @tmp_procname = QUOTENAME(@owner) + '.' + QUOTENAME(@upd_procname)
  18753.             exec ('drop proc ' + @tmp_procname)
  18754.             if @@ERROR<>0 return (1)
  18755.             update sysmergearticles set update_proc = NULL where pubid=@pubid and artid=@artid
  18756.  
  18757.         end
  18758.     if (@sel_procname IS NOT NULL) and exists (select * from sysobjects where
  18759.             name = @sel_procname and type = 'P')
  18760.         begin
  18761.             select @owner = user_name(uid) from sysobjects where name=@sel_procname
  18762.             select @tmp_procname = QUOTENAME(@owner) + '.' + QUOTENAME(@sel_procname)
  18763.             exec ('drop proc ' + @tmp_procname)
  18764.             if @@ERROR<>0 return (1)
  18765.             update sysmergearticles set select_proc = NULL where pubid=@pubid and artid=@artid
  18766.         end
  18767.  
  18768.     if (@view_sel_proc IS NOT NULL) and exists (select * from sysobjects where
  18769.             name = @view_sel_proc and type = 'P')
  18770.         begin
  18771.             select @owner = user_name(uid) from sysobjects where name=@view_sel_proc
  18772.             select @tmp_procname = QUOTENAME(@owner) + '.' + QUOTENAME(@view_sel_proc)
  18773.             exec ('drop proc ' + @tmp_procname)
  18774.             if @@ERROR<>0 return (1)
  18775.             update sysmergearticles set view_sel_proc = NULL where pubid=@pubid and artid=@artid
  18776.         end
  18777.  
  18778.     if (@conf_procname IS NOT NULL) and    not exists (select * from sysmergearticles where
  18779.             artid=@artid and pubid<>@pubid) and exists (select * from sysobjects where
  18780.             name = @conf_procname and type = 'P')
  18781.         begin
  18782.             select @owner = user_name(uid) from sysobjects where name=@conf_procname
  18783.             select @tmp_procname = QUOTENAME(@owner) + '.' + QUOTENAME(@conf_procname)
  18784.             exec ('drop proc ' + @tmp_procname)
  18785.             if @@ERROR<>0 return (1)
  18786.             update sysmergearticles set ins_conflict_proc = NULL where pubid=@pubid and artid=@artid
  18787.         end
  18788.     
  18789.     return 0        
  18790.  
  18791. GO
  18792.  
  18793. exec dbo.sp_MS_marksystemobject sp_MSdroparticleprocs
  18794. go
  18795.  
  18796. raiserror('Creating procedure sp_MSdroparticletriggers', 0,1)
  18797. GO
  18798.  
  18799. /*
  18800. ** We need to qualify sysmergearticle with pubid
  18801. */
  18802. create procedure sp_MSdroparticletriggers
  18803.     (@source_table nvarchar(270),
  18804.      @table_owner    sysname = NULL)
  18805. as
  18806.     set nocount on
  18807.     declare @instrigger     nvarchar(270)
  18808.     declare @updtrigger     nvarchar(270)
  18809.     declare @deltrigger     nvarchar(270)
  18810.     declare @retcode        int
  18811.     declare @owner            sysname
  18812.     declare @artid            uniqueidentifier
  18813.     declare @guidstr        nvarchar(32)
  18814.  
  18815.     -- PARSENAME VARS
  18816.     declare      @UnqualName      sysname  --rightmost name node
  18817.     declare      @QualName1       sysname  
  18818.     -- END PARSENAME VARS
  18819.  
  18820.     select @UnqualName = PARSENAME(@source_table, 1)
  18821.     select @QualName1 = PARSENAME(@source_table, 2)
  18822.     if @UnqualName IS NULL
  18823.          return 1
  18824.     if @QualName1 is not NULL
  18825.         select @owner = @QualName1
  18826.             else if @table_owner is not NULL 
  18827.                 select @owner = @table_owner
  18828.                     else select @owner='dbo'
  18829.     
  18830.     select @artid = artid from sysmergearticles where objid = object_id(@source_table)
  18831.  
  18832.     exec @retcode=sp_MSguidtostr @artid, @guidstr out
  18833.     if @retcode<>0 or @@ERROR<>0 return (1)
  18834.  
  18835.     select @instrigger = QUOTENAME(@owner) + '.ins_' + @guidstr
  18836.     select @updtrigger = QUOTENAME(@owner) + '.upd_' + @guidstr
  18837.     select @deltrigger = QUOTENAME(@owner) + '.del_' + @guidstr
  18838.     
  18839. /*    
  18840.     select @instrigger = sysobjects.name from sysobjects where 
  18841.         ObjectProperty (sysobjects.id, 'ExecIsInsertTrigger') = 1 
  18842.         and ObjectProperty (sysobjects.id, 'IsMSShipped') = 1 
  18843.         and parent_obj = OBJECT_ID(@source_table) 
  18844.  
  18845.     select @updtrigger = sysobjects.name from sysobjects where 
  18846.         ObjectProperty (sysobjects.id, 'ExecIsUpdateTrigger') = 1 
  18847.         and ObjectProperty (sysobjects.id, 'IsMSShipped') = 1 
  18848.         and parent_obj = OBJECT_ID(@source_table) 
  18849.  
  18850.     select @deltrigger = sysobjects.name from sysobjects where 
  18851.         ObjectProperty (sysobjects.id, 'ExecIsDeleteTrigger') = 1 
  18852.         and ObjectProperty (sysobjects.id, 'IsMSShipped') = 1 
  18853.         and parent_obj = OBJECT_ID(@source_table) 
  18854. */
  18855.  
  18856.     if object_id(@instrigger) is not NULL
  18857.         begin
  18858.             exec ('drop trigger ' + @instrigger)
  18859.             if @@ERROR<>0 return (1)
  18860.         end
  18861.     if object_id(@updtrigger) is not NULL
  18862.         begin
  18863.             exec ('drop trigger ' + @updtrigger)
  18864.             if @@ERROR<>0 return (1)
  18865.         end
  18866.     if object_id(@deltrigger) IS NOT NULL
  18867.         begin
  18868.             exec ('drop trigger ' + @deltrigger)
  18869.             if @@ERROR<>0 return (1)
  18870.         end
  18871.  
  18872.     return 0
  18873. GO
  18874.  
  18875. exec dbo.sp_MS_marksystemobject sp_MSdroparticletriggers
  18876. go
  18877.  
  18878.  
  18879. raiserror('Creating procedure sp_mergesubscription_cleanup', 0,1)
  18880. GO
  18881.  
  18882. CREATE PROCEDURE sp_mergesubscription_cleanup (
  18883.     @publisher        sysname,
  18884.     @publisher_db    sysname,
  18885.     @publication     sysname
  18886.     ) AS
  18887.     declare @pubid                 uniqueidentifier
  18888.     declare @artid                 uniqueidentifier
  18889.     declare @retcode            smallint
  18890.     declare @subscription_type  int
  18891.     declare @objid              int
  18892.     declare @objectname         sysname
  18893.     declare @objectowner        sysname
  18894.  
  18895.     /* 
  18896.     ** Security check
  18897.     */
  18898.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  18899.     IF @@ERROR <> 0 or @retcode <> 0
  18900.         RETURN(1)
  18901.         
  18902.     /*
  18903.     ** if there is nothing to cleanup, then just return.
  18904.     */
  18905.     if not exists (select * from sysobjects where name='sysmergesubscriptions')
  18906.         return (0)
  18907.         
  18908.     /* This only gets called after database is enable to subscribe, so sysmergepublications should exist */
  18909.     select @pubid = pubid FROM sysmergepublications 
  18910.         WHERE name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db
  18911.  
  18912.     /* Normal case - nothing to cleanup, just return */
  18913.     if @pubid is null
  18914.         return (1)
  18915.  
  18916.     select @subscription_type = subscription_type from sysmergesubscriptions where pubid=@pubid and subid<>pubid
  18917.  
  18918.     /* This procedure is not intended to be used for cleanning-up pull/anonymous subscriptions */
  18919.     if @subscription_type > 0
  18920.         begin
  18921.             raiserror(20091, 16, -1)
  18922.             return (1)
  18923.         end
  18924.  
  18925.     /* Clean up the articles for this publication, and delete the row */
  18926.     select @artid = artid FROM sysmergearticles WHERE pubid = @pubid
  18927.     while @artid is not null
  18928.         begin
  18929.         if not exists (select * from sysmergearticles WHERE artid = @artid and pubid <> @pubid)
  18930.             begin
  18931.                 exec @retcode=sp_MSarticlecleanup @pubid, @artid
  18932.                 if @retcode<>0 or @@ERROR<>0 return (1)
  18933.             end
  18934.         delete from sysmergearticles where artid = @artid and pubid = @pubid
  18935.         set @artid = NULL
  18936.         select @artid = artid FROM sysmergearticles WHERE pubid = @pubid
  18937.         end
  18938.         
  18939.     /* Cleanup the schema articles */
  18940.  
  18941.     /* Unmark all schema article objects unconditionally */
  18942.     if exists (select * from sysobjects where name = 'sysmergeschemaarticles')
  18943.     begin
  18944.         declare hschemaarticle_cur cursor local fast_forward for
  18945.             select destination_object, destination_owner from sysmergeschemaarticles where
  18946.             pubid = @pubid 
  18947.         for read only
  18948.         open hschemaarticle_cur
  18949.         fetch hschemaarticle_cur into @objectname, @objectowner
  18950.         while (@@fetch_status<>-1)
  18951.         begin
  18952.                 -- Ignore errors
  18953.                 exec  sp_MSunmarkschemaobject @objectname, @objectowner    
  18954.                 fetch hschemaarticle_cur into @objectname, @objectowner
  18955.         end
  18956.         close hschemaarticle_cur
  18957.         deallocate hschemaarticle_cur
  18958.  
  18959.         /* Delete all schema article rows for this publication*/
  18960.         delete from sysmergeschemaarticles where pubid = @pubid
  18961.     end
  18962.  
  18963.     /* 
  18964.     ** Make sure you NULL out gen_cur for other articles that share this table 
  18965.     ** since we are deleting the genhistroy row for that generation 
  18966.     */
  18967.     update sysmergearticles set gen_cur=NULL where gen_cur in
  18968.         (select generation from MSmerge_genhistory where pubid = @pubid)
  18969.  
  18970.     /* Now clean up any traces in other system tables */
  18971.     delete from MSmerge_genhistory where pubid = @pubid 
  18972.     delete from MSmerge_replinfo where repid in (select subid from sysmergesubscriptions where pubid = @pubid)
  18973.     delete from sysmergesubscriptions where pubid = @pubid
  18974.     delete from sysmergepublications where pubid = @pubid
  18975.     delete from sysmergeschemachange where pubid = @pubid
  18976.     /* 
  18977.     ** If last subscription is dropped and the DB is not enabled for publishing,
  18978.     ** then remove the merge system tables
  18979.     */
  18980.     IF (not exists (select * from sysmergesubscriptions )) 
  18981.         AND (select category & 4 FROM master..sysdatabases WHERE name = DB_NAME() collate database_default )=0
  18982.     BEGIN
  18983.         execute @retcode = dbo.sp_MSdrop_mergesystables
  18984.         if @@ERROR <> 0 or @retcode <> 0
  18985.         begin
  18986.             return (1)
  18987.         end
  18988.     END    
  18989. GO
  18990. exec dbo.sp_MS_marksystemobject sp_mergesubscription_cleanup
  18991. go
  18992. grant execute on dbo.sp_mergesubscription_cleanup to public
  18993.  
  18994. raiserror('Creating procedure sp_subscription_cleanup', 0,1)
  18995. GO
  18996. CREATE PROCEDURE sp_subscription_cleanup (
  18997.     @publisher        sysname,
  18998.     @publisher_db    sysname,
  18999.     @publication    sysname = NULL,
  19000.     @reserved        nvarchar(10) = NULL
  19001. )
  19002. AS
  19003. BEGIN
  19004.  
  19005.     declare @object_name sysname
  19006.             ,@object_type char(2)
  19007.             ,@independent_agent bit
  19008.             ,@retcode int
  19009.             ,@synctran_bit int
  19010.             ,@parent_obj int
  19011.             ,@object_id int
  19012.             ,@cmd nvarchar(4000)
  19013.  
  19014.     select @synctran_bit            = 256
  19015.  
  19016.     /*
  19017.     ** Security Check
  19018.     */
  19019.  
  19020.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  19021.     IF @@ERROR <> 0 or @retcode <> 0
  19022.         RETURN(1)
  19023.  
  19024.     if @publication = '' OR @publication is NULL
  19025.         select @independent_agent = 0
  19026.     else
  19027.         select @independent_agent = 1
  19028.  
  19029.     IF exists (select name from sysobjects where name = 'MSreplication_objects')
  19030.     BEGIN
  19031.         declare object_cursor CURSOR LOCAL FAST_FORWARD for 
  19032.             select DISTINCT object_name, object_type from MSreplication_objects o
  19033.                     where (UPPER(o.publisher) = UPPER(@publisher) and
  19034.                         o.publisher_db = @publisher_db and
  19035.                         o.publication = @publication) or
  19036.                         @reserved = 'drop_all'
  19037.  
  19038.         OPEN object_cursor
  19039.         FETCH object_cursor INTO @object_name, @object_type
  19040.          WHILE (@@fetch_status <> -1)
  19041.               BEGIN
  19042.                   IF @object_type = 'T' 
  19043.                   begin
  19044.                     select @parent_obj = NULL
  19045.                     select @parent_obj = parent_obj, @object_id = id from
  19046.                         sysobjects where name = @object_name 
  19047.                     if @parent_obj is not null
  19048.                     begin
  19049.                         -- Unmark synctran bit
  19050.                         update sysobjects set replinfo = replinfo & ~@synctran_bit where 
  19051.                             id = @parent_obj and
  19052.                             (replinfo & @synctran_bit) <> 0
  19053.                         IF @@ERROR <> 0 
  19054.                             GOTO UNDO
  19055.                         exec @retcode = dbo.sp_MSdrop_object 
  19056.                             @object_id = @object_id
  19057.                         if @retcode <> 0 or @@error <> 0
  19058.                             goto UNDO
  19059.  
  19060.                         -- Clean up identity range entry
  19061.                         -- Since we only support one trigger per subscriber table
  19062.                         -- we assume identity range row can not be reused by multiple
  19063.                         -- subscriptions.
  19064.                         IF EXISTS(select * from sysobjects where type='U' and name = 'MSsub_identity_range')
  19065.                         BEGIN
  19066.                             if exists (select * from MSsub_identity_range where objid = @parent_obj)
  19067.                             begin
  19068.                                 -- Drop the identity range constraits.
  19069.                                 exec @retcode = dbo.sp_MSreseed
  19070.                                     @objid =  @parent_obj,
  19071.                                     -- range or seed can be anything
  19072.                                     @next_seed = 10,
  19073.                                     @range = 10,
  19074.                                     @is_publisher = -1,
  19075.                                     @check_only = 1,
  19076.                                     @drop_only = 1
  19077.                                 IF @retcode <> 0 or @@ERROR <> 0 
  19078.                                     GOTO UNDO
  19079.  
  19080.                                 delete MSsub_identity_range where objid = @parent_obj
  19081.                                 IF @@ERROR <> 0 
  19082.                                     GOTO UNDO
  19083.                             end
  19084.  
  19085.                             IF NOT EXISTS (SELECT * FROM MSsub_identity_range)
  19086.                             BEGIN
  19087.                                 DROP TABLE MSsub_identity_range
  19088.                                 IF @@ERROR <> 0 
  19089.                                     GOTO UNDO
  19090.                             END
  19091.                         END
  19092.                     end
  19093.                   end
  19094.                   delete from MSreplication_objects where object_name=@object_name
  19095.                   FETCH object_cursor INTO @object_name, @object_type
  19096.               END
  19097.         CLOSE object_cursor
  19098.         DEALLOCATE object_cursor
  19099.         
  19100.         if not exists (select * from MSreplication_objects) 
  19101.         begin
  19102.             drop table MSreplication_objects
  19103.             IF @@ERROR <> 0 
  19104.                 GOTO UNDO
  19105.         end
  19106.         
  19107.     END
  19108.  
  19109.     --
  19110.     -- cleanup queued conflict tables
  19111.     --
  19112.     IF exists (select name from dbo.sysobjects where name = 'MSsubscription_agents')
  19113.     BEGIN
  19114.         declare        @agent_id int
  19115.                     ,@cft_table sysname
  19116.                     ,@owner sysname
  19117.  
  19118.         --
  19119.         -- first get the agent(s) for this queued subscription(s) and 
  19120.         -- 
  19121.         declare #agent_cursor CURSOR LOCAL FAST_FORWARD for 
  19122.             select id from dbo.MSsubscription_agents 
  19123.             where ((UPPER(publisher) = UPPER(@publisher) and 
  19124.                     publisher_db = @publisher_db and 
  19125.                     publication = @publication) or (@reserved = 'drop_all')) and
  19126.                     update_mode in (2,3,4,5)
  19127.  
  19128.         open #agent_cursor
  19129.         fetch #agent_cursor into @agent_id
  19130.         while (@@fetch_status != -1)
  19131.         begin
  19132.             --
  19133.             -- drop the conflict table for each article in this subscription
  19134.             --
  19135.             if exists (select name from dbo.sysobjects where name = 'MSsubscription_articles')
  19136.             begin
  19137.             
  19138.                 declare #object_cursor CURSOR LOCAL FAST_FORWARD for 
  19139.                     select owner, cft_table from dbo.MSsubscription_articles
  19140.                     where agent_id = @agent_id
  19141.  
  19142.                 OPEN #object_cursor
  19143.                 FETCH #object_cursor INTO @owner, @cft_table
  19144.                 WHILE (@@fetch_status != -1)
  19145.                 BEGIN
  19146.                     --
  19147.                     -- drop the conflict table(s) for this article - ignore errors
  19148.                     --
  19149.                     select @cmd = case 
  19150.                         when (@owner IS NULL) then
  19151.                             N'if exists (select * from dbo.sysobjects where name = N''' + 
  19152.                             master.dbo.fn_MSgensqescstr(@cft_table) collate database_default + ''') drop table ' + 
  19153.                             quotename(master.dbo.fn_MSgensqescstr(@cft_table)) collate database_default
  19154.                         else
  19155.                             N'if exists (select * from dbo.sysobjects where name = N''' + 
  19156.                             master.dbo.fn_MSgensqescstr(@cft_table) collate database_default + ''') drop table ' + 
  19157.                             quotename(master.dbo.fn_MSgensqescstr(@owner)) collate database_default + N'.' +
  19158.                             quotename(master.dbo.fn_MSgensqescstr(@cft_table)) collate database_default
  19159.                         end
  19160.                     execute ( @cmd )
  19161.  
  19162.                     -- get next row
  19163.                     FETCH #object_cursor INTO @owner, @cft_table
  19164.                 END
  19165.                 CLOSE #object_cursor
  19166.                 DEALLOCATE #object_cursor
  19167.  
  19168.                 --
  19169.                 -- delete entries from MSsubscription_articles for this agent id
  19170.                 --
  19171.                 delete dbo.MSsubscription_articles where agent_id = @agent_id
  19172.  
  19173.                 --
  19174.                 -- drop MSsubscription_articles if empty (should we do it)
  19175.                 -- 
  19176.                 IF NOT EXISTS (SELECT * FROM dbo.MSsubscription_articles)
  19177.                 BEGIN
  19178.                     DROP TABLE dbo.MSsubscription_articles
  19179.                     IF @@ERROR != 0 
  19180.                         GOTO UNDO
  19181.                 END
  19182.             end
  19183.  
  19184.             --
  19185.             -- get the next agent
  19186.             --
  19187.             fetch #agent_cursor into @agent_id
  19188.         end
  19189.         close #agent_cursor
  19190.         deallocate #agent_cursor
  19191.     END
  19192.  
  19193.     --
  19194.     -- clean discarded queued transactions
  19195.     --
  19196.     if exists (select name from dbo.sysobjects where name = 'MSreplication_queue')
  19197.     begin
  19198.         delete dbo.MSreplication_queue
  19199.         where (publisher = UPPER(@publisher) and 
  19200.                 publisher_db = @publisher_db and 
  19201.                 publication = @publication) or 
  19202.                 @reserved = 'drop_all'
  19203.     end
  19204.     if exists (select name from dbo.sysobjects where name = 'MSrepl_queuedtraninfo')
  19205.     begin
  19206.         delete dbo.MSrepl_queuedtraninfo
  19207.         where (publisher = UPPER(@publisher) and 
  19208.                 publisher_db = @publisher_db and 
  19209.                 publication = @publication) or 
  19210.                 @reserved = 'drop_all'
  19211.     end
  19212.     
  19213.     IF exists (select name from sysobjects where name = 'MSreplication_subscriptions')
  19214.     BEGIN
  19215.     delete from MSreplication_subscriptions 
  19216.         where (UPPER(publisher) = UPPER(@publisher) AND
  19217.               publisher_db = @publisher_db AND
  19218.               -- Drop the subscription as long as the publication name matches even if
  19219.               -- the publication is not independent agent
  19220.               -- This behaviour is expected by sp_droppullsubscription
  19221.               -- -- independent_agent = @independent_agent and 
  19222.               ((@independent_agent=0 and independent_agent = 0) or 
  19223.               publication = @publication))
  19224.               or @reserved = 'drop_all'
  19225.  
  19226.         IF NOT EXISTS (SELECT * FROM MSreplication_subscriptions)
  19227.         BEGIN
  19228.             DROP TABLE MSreplication_subscriptions
  19229.             IF @@ERROR <> 0 
  19230.                 GOTO UNDO
  19231.         END
  19232.     END
  19233.  
  19234.  
  19235.     IF exists (select name from sysobjects where name = 'MSsubscription_agents')
  19236.     BEGIN
  19237.         delete from MSsubscription_agents
  19238.         where (UPPER(publisher) = UPPER(@publisher) AND
  19239.               publisher_db = @publisher_db AND
  19240.               -- Drop the subscription as long as the publication name matches even if
  19241.               -- the publication is not independent agent
  19242.               -- This behaviour is expected by sp_droppullsubscription
  19243.               (publication = @publication or
  19244.                (@independent_agent=0 and publication = N'ALL')))
  19245.               or @reserved = 'drop_all'
  19246.  
  19247.         -- Delete the agent entry if no corresponding rows found in MSreplication_subscription
  19248.         -- table.
  19249.         -- This is to cleanup share agent entry.
  19250.         -- This behaviour is expected by sp_droppullsubscription
  19251.         if object_id('MSreplication_subscriptions') is not null
  19252.         begin
  19253.             if not exists (select * from MSreplication_subscriptions s where
  19254.                     s.publisher = @publisher and
  19255.                     s.publisher_db = @publisher_db and
  19256.                     s.independent_agent = 0)
  19257.                 delete from MSsubscription_agents where
  19258.                     publisher = @publisher and
  19259.                     publisher_db = @publisher_db and
  19260.                     publication = N'ALL'
  19261.         end
  19262.         else
  19263.             delete  MSsubscription_agents
  19264.  
  19265.         IF NOT EXISTS (SELECT * FROM MSsubscription_agents)
  19266.         BEGIN
  19267.             DROP TABLE MSsubscription_agents
  19268.             IF @@ERROR <> 0 
  19269.                 GOTO UNDO
  19270.         END
  19271.     END
  19272.  
  19273.     IF EXISTS(select * from sysobjects where type=N'U' and name = 'MSsubscription_properties')
  19274.     BEGIN
  19275.         DELETE FROM MSsubscription_properties 
  19276.         WHERE (UPPER(publisher) = UPPER(@publisher)    AND
  19277.         publisher_db  = @publisher_db AND
  19278.         publication = @publication) 
  19279.         or @reserved = 'drop_all'
  19280.  
  19281.         IF @@ERROR <> 0 
  19282.             GOTO UNDO
  19283.  
  19284.         IF NOT EXISTS (SELECT * FROM MSsubscription_properties)
  19285.         BEGIN
  19286.             exec @retcode = dbo.sp_MSsub_cleanup_prop_table
  19287.             IF @@ERROR <> 0 or @retcode <> 0
  19288.                 GOTO UNDO
  19289.         END
  19290.     END
  19291.  
  19292.     -- Ignore errors.
  19293.     exec dbo.sp_MSsub_cleanup_orphans
  19294.     
  19295.     return (0)
  19296.             
  19297. UNDO:
  19298.     return(1)
  19299. END
  19300. GO
  19301. exec dbo.sp_MS_marksystemobject sp_subscription_cleanup 
  19302. go
  19303.  
  19304.  
  19305. raiserror('Creating procedure sp_get_distributor', 0,1)
  19306. go
  19307.  
  19308. -- Called by the UI to find out if the distributor is installed without doing RPC.
  19309. CREATE PROCEDURE sp_get_distributor 
  19310. AS
  19311.     SET NOCOUNT ON
  19312.  
  19313.     /*
  19314.     ** Declarations.
  19315.     */
  19316.     DECLARE @distributor sysname
  19317.     DECLARE @installed bit
  19318.     declare @distdb_installed bit
  19319.     declare @is_distpublisher bit
  19320.     declare @has_remote_distpublisher bit
  19321.      declare @distbit int
  19322.  
  19323.     SELECT @distbit = 16
  19324.        
  19325.     SELECT @distributor = datasource FROM master..sysservers
  19326.         WHERE srvstatus & 8 <> 0
  19327.  
  19328.     if @distributor is not null
  19329.         select @installed = 1
  19330.     else
  19331.         select @installed = 0
  19332.  
  19333.     if UPPER(@distributor) = UPPER(@@servername)
  19334.     begin
  19335.         if exists (select * from msdb.dbo.MSdistributiondbs) 
  19336.             select @distdb_installed = 1
  19337.         else
  19338.             select @distdb_installed = 0
  19339.  
  19340.         if exists (select * from msdb..MSdistpublishers where UPPER(name) = UPPER(@@servername) collate database_default)
  19341.             select @is_distpublisher = 1
  19342.         else
  19343.             select @is_distpublisher = 0
  19344.  
  19345.         if exists (select * from msdb..MSdistpublishers where UPPER(name) <> UPPER(@@servername) collate database_default)
  19346.             select @has_remote_distpublisher = 1
  19347.         else
  19348.             select @has_remote_distpublisher = 0
  19349.     end
  19350.     else
  19351.     begin
  19352.         select @distdb_installed = 0
  19353.         select @has_remote_distpublisher = 0    
  19354.         select @is_distpublisher = 0
  19355.     end
  19356.  
  19357.     select 'installed' = @installed, 'distribution server' = @distributor,
  19358.             'distribution db installed' = @distdb_installed,
  19359.             'is distribution publisher' = @is_distpublisher,
  19360.             'has remote distribution publisher' = @has_remote_distpublisher
  19361. GO
  19362.  
  19363. exec dbo.sp_MS_marksystemobject sp_get_distributor
  19364. go
  19365.  
  19366.  
  19367. -- Called by sp_addrolemember
  19368. raiserror('Creating procedure sp_MSrepl_addrolemember', 0,1)
  19369. go
  19370. CREATE PROCEDURE sp_MSrepl_addrolemember
  19371.     @rolename       sysname,
  19372.     @membername     sysname
  19373. AS
  19374.     -- SETUP RUNTIME OPTIONS / DECLARE VARIABLES --
  19375.     set    nocount on
  19376.     
  19377.     return(0)
  19378.  
  19379. go        
  19380.  
  19381. exec dbo.sp_MS_marksystemobject sp_MSrepl_addrolemember
  19382. go
  19383.  
  19384. -- Called by sp_droprolemember
  19385. raiserror('Creating procedure sp_MSrepl_droprolemember', 0,1)
  19386. go
  19387. CREATE PROCEDURE sp_MSrepl_droprolemember
  19388.     @rolename       sysname,
  19389.     @membername     sysname
  19390. AS
  19391.     set    nocount on
  19392.     return(0)
  19393. go        
  19394.  
  19395. exec dbo.sp_MS_marksystemobject sp_MSrepl_droprolemember
  19396. go
  19397.  
  19398. raiserror('Creating procedure sp_table_validation', 0,1)
  19399. go
  19400.  
  19401. create procedure sp_table_validation
  19402. @table sysname,                -- table name or sync object name
  19403. @expected_rowcount bigint = NULL OUTPUT,
  19404. @expected_checksum numeric = NULL OUTPUT,
  19405. @rowcount_only smallint = 1,
  19406. /* 
  19407. The @rowcount_only param is overloaded for shiloh release due to backward compatibility concerns.
  19408. In shiloh, the checksum functionality has changed.   So 7.0 subscribers will have the old checksum 
  19409. routines, which generate different CRC values, and do not have functionality for vertical partitions,
  19410. or logical table structures where column offsets differ (due to ALTER TABLEs that DROP and ADD columns).
  19411.  
  19412. In 7.0, this was a bit column.  0 meant do not do just a rowcount - do a checksum.  1 meant just do a 
  19413. rowcount.
  19414.  
  19415. For Shiloh, this parameter is changed to a smallint.  The name "rowcount_only" is now a 
  19416. misnomer given the overloaded functionality.  It is really a "type of check requested"
  19417. parameter.   But, the old name is retained for backward compatibility.   It can take 
  19418. these values:
  19419.  
  19420. 0 - Do a 7.0 compatible checksum
  19421. 1 - Do a rowcount check only (remains the default)
  19422. 2 - Use new Shiloh checksum functionality.  
  19423.  
  19424. Note that because 7.0 subscribers will 
  19425. take this parameter as a bit type, not a smallint, it will be interpreted as simply
  19426. ON.  That means that passing a 2, and having a 7.0 subscriber, will result in the 7.0
  19427. subscriber doing only rowcount validation.   The Shiloh subscribers will do both
  19428. rowcount and checksum.  If you want 7.0 subscribers to do checksum validation, use 
  19429. the value of 0 for this parameter.   Shiloh subscribers can do the 7.0 compatible 
  19430. checksum, but that checksum has the same 7.0 limitations for vertical partitions 
  19431. and differences in physical table structure.)
  19432.  
  19433. */
  19434.  
  19435. @owner    sysname = NULL,
  19436. @full_or_fast tinyint = 2,        -- full (value 0) does COUNT(*) 
  19437.                     -- fast (value 1) uses sysindexes.rowcnt if table (not view); 
  19438.                     -- conditional fast (VALUE 2) , first tries fast method, but
  19439.                     -- reverts to full if fast method shows differences.
  19440. @shutdown_agent bit = 0,         -- If 1 will raise error 20578, which will signal replication agent to shutdown
  19441. @table_name sysname    = NULL,        -- table name of sync object or the table name for output message,
  19442. @column_list nvarchar(4000) = NULL     -- the list of columns - that way the user can skip computed columns etc
  19443.  
  19444. as
  19445.  
  19446. set nocount on
  19447.  
  19448. declare @num_rows bigint
  19449. declare @checksum numeric
  19450. declare @checksum_string varchar(100)
  19451. declare @expected_checksum_string varchar(21)
  19452. declare @rowcount_string varchar(21)
  19453. declare @exp_rowcount_string varchar(21)
  19454. declare @width int
  19455. declare @qualified_table_name nvarchar(262)  -- two names plus []'s and a .
  19456. declare @temp_table_used bit
  19457. declare @retstatus int
  19458. declare @failed_fast tinyint
  19459. declare @min_indid int
  19460. declare @asked_for_exp_checksum tinyint
  19461. declare @asked_for_exp_rows tinyint
  19462.  
  19463.  
  19464.  
  19465. SET @retstatus=0    -- initialize to SUCCESS
  19466. SET @failed_fast=0
  19467.  
  19468.  
  19469. if (@expected_checksum IS NULL AND isnull(@rowcount_only,-9999) <> 1 )  -- Wants an expected checksum value
  19470.     SET @asked_for_exp_checksum=1
  19471. ELSE
  19472.     SET @asked_for_exp_checksum=0
  19473.  
  19474.  
  19475. if (@expected_rowcount IS NULL)  -- Wants an expected rowcount value
  19476.     SET @asked_for_exp_rows=1
  19477. ELSE
  19478.     SET @asked_for_exp_rows=0
  19479.  
  19480. -- Only values 0,1,2 make sense for @rowcount_only. 
  19481. if (@rowcount_only NOT BETWEEN 0 and 2)
  19482.     BEGIN
  19483.     -- msg 20543 says that @rowcount_only must be 0,1,2 and explains the values.
  19484.     RAISERROR (20543,16,-1,@qualified_table_name)
  19485.     SET @retstatus=1
  19486.     return @retstatus
  19487.     END
  19488.  
  19489. -- RHS:  
  19490. -- Some states do not make sense.  For example,  it does not make sense to ask for conditional
  19491. -- fast row count checking, yet not provide an expected value.  If this is done, provide a warning
  19492. -- message and use fast checking method.
  19493. if (@full_or_fast = 2 AND @expected_rowcount IS NULL)
  19494.     BEGIN
  19495.     -- (20559,10,0,'Conditional Fast Rowcount method requested without specifying an expected count. Fast method will be used.', 1033)
  19496.     raiserror (20559, 10, -1)
  19497.     SET @full_or_fast = 1
  19498.     END
  19499.  
  19500. -- Another state that doesn't make sense is to pass an expected checksum value, yet
  19501. -- ask for rowcount only validation
  19502. if (@expected_checksum IS NOT NULL AND @rowcount_only = 1)
  19503.     BEGIN
  19504.     -- (Msg 20560,10,0,'An expected checksum value was passed, but checksums will not be compared because rowcount only checking was requested.', 1033)
  19505.     raiserror (20560, 10, -1)
  19506.     SET @expected_checksum = NULL
  19507.     END
  19508.  
  19509.  
  19510. if @owner is null
  19511. begin
  19512.     if left(ltrim(rtrim(@table)), 1) <> '[' or right(ltrim(rtrim(@table)), 1) <> ']'
  19513.         set @qualified_table_name = '[' + @table + ']'
  19514.     else
  19515.         set @qualified_table_name = @table
  19516. end
  19517. else
  19518. begin
  19519.     if left(ltrim(rtrim(@table)), 1) <> '[' or right(ltrim(rtrim(@table)), 1) <> ']'
  19520.         set @qualified_table_name = '[' + @owner + '].[' + @table + ']'
  19521.     else
  19522.         set @qualified_table_name = '[' + @owner + '].' + @table
  19523. end
  19524.  
  19525. IF (OBJECT_ID(@qualified_table_name) IS NULL)
  19526.     -- No such object.  Return with error.
  19527.     BEGIN
  19528.     -- Msg (20585,10,0,'Object '%s' does not exist.  Exiting validation check.', 1033)  
  19529.     RAISERROR (20585,16,-1,@qualified_table_name)
  19530.     SET @retstatus=1
  19531.     return @retstatus
  19532.     END
  19533.  
  19534. -- If the object is a table (not view) and fast checking (1) requested,
  19535. -- then get rowcount from sysindexes, rather than scanning.
  19536. -- Fast rowcount method gets value from sysindexes - and the row_cnt value is only maintained for tables.
  19537.  
  19538. IF (SELECT @full_or_fast) > 0    -- IF Fast row checking asked for
  19539.     AND 
  19540.    (SELECT OBJECTPROPERTY(OBJECT_ID(@qualified_table_name),'IsTable')) > 0  -- Must be a table, not a view
  19541.  
  19542.     BEGIN
  19543.         -- Do the fast rowcount method
  19544.         -- Temporarily put a SHARE lock on table to ensure no simultaneous updates going on
  19545.         -- Minimizes chances of getting an out of date value from sysindexes.   True that
  19546.         -- it reduces concurrency, but if the fast method doesnt work the user will very likely
  19547.         -- go do the full method, which will be much more costly.   Better I think to take a little more cost here
  19548.         -- and hopefully get a good number.   The @foo variable is used so that its an
  19549.         -- assignment and doesn't make another result set get returned.
  19550.  
  19551.         BEGIN TRAN
  19552.         EXEC ('DECLARE @foo int SELECT @foo=1 FROM ' + @qualified_table_name + ' (TABLOCK HOLDLOCK) WHERE 1=2')
  19553.         SELECT @num_rows=rowcnt,@min_indid=indid FROM sysindexes WHERE id=OBJECT_ID(@qualified_table_name)and indid < 2
  19554.         COMMIT TRAN
  19555.     END
  19556.  
  19557. ELSE 
  19558.     SET @full_or_fast = 0   -- Full checking will be used, regardless of whether it was requested
  19559.  
  19560. --    set the output name if not set
  19561.     if (@table_name IS NULL)
  19562.         SELECT @table_name = @table
  19563.  
  19564. -- If fast row checking was used, and request for rowcount check only, we're done.
  19565. if (@full_or_fast = 1  AND  @rowcount_only = 1) 
  19566.     GOTO ROWCOUNT_MSG
  19567.     
  19568. -- If conditional fast row checking was used, and request for rowcount check only, 
  19569. -- we're also done IFF rows and expected rows match.
  19570. if (@full_or_fast = 2  AND  @rowcount_only = 1 
  19571.     AND @expected_rowcount IS NOT NULL AND @expected_rowcount=@num_rows)
  19572.     BEGIN
  19573.         -- Fast checking was actually used.
  19574.         SET @full_or_fast = 1
  19575.         GOTO ROWCOUNT_MSG
  19576.     END
  19577.  
  19578.  
  19579. -- If we're still here we are doing full row checking at a minimum, and will need the temp table
  19580.  
  19581. IF (SELECT ISNULL(OBJECT_ID('tempdb..#tab_validt1'),0)) = 0    -- Table Does Not exist
  19582.     CREATE TABLE #tab_validt1 (tmp_rows bigint NULL, tmp_checksum numeric NULL)
  19583. ELSE -- table already exists 
  19584.     TRUNCATE TABLE #tab_validt1
  19585.  
  19586. -- If we are only doing row checking, we'll do it here.  If we will do both row checking 
  19587. -- and checksum, then do them together so as to not scan table twice.
  19588.  
  19589.  
  19590. if @rowcount_only = 1
  19591.     BEGIN   -- Must do full count(*) checking but not checksums
  19592.     
  19593.     if @full_or_fast=2   
  19594.         -- if we are here with conditional check (2) requested, it is because
  19595.         -- a conditional was possible, but it failed.  We wiil later alert user of this.
  19596.         BEGIN 
  19597.         SET @full_or_fast=0
  19598.         SET @failed_fast=1
  19599.         END
  19600.  
  19601.     insert into #tab_validt1 (tmp_rows,tmp_checksum) 
  19602.         exec ('select count_big(*), NULL from ' +    @qualified_table_name + ' (TABLOCK HOLDLOCK)')
  19603.  
  19604.     -- Get row count value
  19605.     select  TOP 1 @num_rows = tmp_rows from #tab_validt1   -- Should only be one row
  19606.         
  19607.     -- IF there were no rows from above, the table was empty so use ZERO.
  19608.     IF @num_rows IS NULL
  19609.         SELECT @num_rows=0
  19610.  
  19611.     -- Done with the temp table
  19612.     DROP TABLE #tab_validt1
  19613.     
  19614.     IF @expected_rowcount IS NULL
  19615.         BEGIN
  19616.         SET @expected_rowcount = @num_rows
  19617.         END
  19618.     GOTO ROWCOUNT_MSG
  19619.     END -- Done with full row count only
  19620.  
  19621. ELSE  -- Doing checksums in addition to ROWCOUNT
  19622.  
  19623.     BEGIN    -- DO checksum and rowcount in same pass thru the table
  19624.     -- Decide whether must use the 7.0 compatible checksum, or use the Shiloh checksum:
  19625.     
  19626.     IF (@rowcount_only = 0)   -- 7.0 Compatible Checksum
  19627.         BEGIN
  19628.         insert into #tab_validt1 (tmp_rows,tmp_checksum)
  19629.             exec ('select count_big(*), sum (convert(numeric, getchecksum(NULL,1))) from ' +    @qualified_table_name + ' (TABLOCK HOLDLOCK)')
  19630.         END
  19631.     ELSE
  19632.     
  19633.         BEGIN  -- Shiloh Checksum
  19634.         
  19635.         
  19636.         if @column_list IS NULL OR @column_list = ' * '
  19637.             begin
  19638.                 insert into #tab_validt1 (tmp_rows,tmp_checksum)
  19639.                     exec ('select count_big(*), sum (convert(numeric, binary_checksum(*) ) ) from ' +    @qualified_table_name + ' (TABLOCK HOLDLOCK)')
  19640.             end
  19641.         else
  19642.             begin
  19643.                 insert into #tab_validt1 (tmp_rows,tmp_checksum)
  19644.                     exec ('select count_big(*), sum (convert(numeric, binary_checksum( ' + @column_list + ') ) ) from ' +    @qualified_table_name + ' (TABLOCK HOLDLOCK)')
  19645.             
  19646.             end            
  19647.         
  19648.         
  19649.         END
  19650.     -- Get the checksum & rowcount values
  19651.     select TOP 1 @checksum = tmp_checksum, @num_rows= tmp_rows from #tab_validt1
  19652.     
  19653.     -- IF there were no rows from above, the table was empty so use ZERO.
  19654.     IF @checksum IS NULL or @num_rows IS NULL
  19655.         SELECT @checksum=isnull(@checksum,0),@num_rows=isnull(@checksum,0)
  19656.  
  19657.     -- Done with the temp table
  19658.     DROP TABLE #tab_validt1
  19659.     
  19660.     IF @expected_rowcount IS NULL  -- Just getting value - no expected value yet.
  19661.         SET @expected_rowcount = @num_rows
  19662.     
  19663.     -- Validate checksum
  19664.     IF @expected_checksum is null        -- Just getting value - no expected value yet.
  19665.         set @expected_checksum = @checksum
  19666.     else
  19667.         -- Raise error if checksums OR rowcounts do not match
  19668.         if @checksum <> @expected_checksum OR @num_rows <> @expected_rowcount
  19669.             begin
  19670.             -- Checksum failed.
  19671.             SELECT     @checksum_string = convert(varchar(21), @checksum),
  19672.                 @expected_checksum_string = convert(varchar(21), @expected_checksum),
  19673.                 @rowcount_string = convert(varchar(21),@num_rows),
  19674.                 @exp_rowcount_string = convert(varchar(21),@expected_rowcount)
  19675.  
  19676.             -- Msg (20525,10,0,'Table ''%s'' might be out of synchronization. Rowcounts (actual: %s, expected %s). Checksum values (actual: %s, expected: %s).', 1033)
  19677.             raiserror (20525, 10, -1, @table, @rowcount_string, @exp_rowcount_string, @checksum_string, @expected_checksum_string)
  19678.             SET @retstatus=1
  19679.             END
  19680.         else
  19681.         BEGIN
  19682.         -- Row count and checksum validation passed.
  19683.         -- 
  19684.         if @asked_for_exp_checksum=0 -- Only give message if not generating the expected value
  19685.             BEGIN
  19686.             -- Msg (20527,10,0,'Table ''%s'' passed rowcount (%s) and checksum validation. (Note: checksum is not compared for any text and image columns.)', 1033)
  19687.             SET @rowcount_string=convert(varchar(21),@num_rows)
  19688.             raiserror (20527, 10, -1, @table,@rowcount_string)
  19689.             END
  19690.         END
  19691.     -- Done with checksum and rowcount scan.
  19692.     END
  19693. -- We did checksum method, and so are done and skip over the rowcount only messages.
  19694.  
  19695. GOTO ALL_DONE
  19696.  
  19697. ROWCOUNT_MSG:
  19698. -- Raise error if rows counts do not match
  19699.     IF @expected_rowcount IS NULL  -- just return the found value
  19700.         SET @expected_rowcount=@num_rows
  19701.     ELSE
  19702.         IF @num_rows <> @expected_rowcount
  19703.         begin
  19704.             SELECT     @rowcount_string=convert(varchar(21),@num_rows),
  19705.                 @exp_rowcount_string=convert(varchar(21),@expected_rowcount)
  19706.             -- Msg (20524,10,0,'Table ''%s'' may be out of synchronization. Rowcounts (actual: %s, expected: %s). Rowcount method %d used (0 = Full, 1 = Fast).', 1033)
  19707.             raiserror (20524, 10, -1, @table_name, @rowcount_string, @exp_rowcount_string, @full_or_fast )
  19708.             SET @retstatus=1
  19709.         end
  19710.         ELSE    -- Row count validation passed. 
  19711.         begin
  19712.             SET @rowcount_string=convert(varchar(21),@num_rows)
  19713.             if @asked_for_exp_rows=0 -- Only give message if not generating the expected value
  19714.                   -- Msg (20526,10,0,'Table ''%s'' passed rowcount (%s) validation. Rowcount method %d used (0 = Full, 1 = Fast).', 1033)
  19715.  
  19716.                 raiserror (20526, 10, -1, @table_name, @rowcount_string, @full_or_fast)
  19717.             
  19718.             if @failed_fast=1
  19719.             BEGIN
  19720.             -- if we had to revert to FULL on a CONDITIONAL FAST, Make that known too.
  19721.             -- And Update usage to fix the problem
  19722.             -- Msg 20558: 'Table ''%s'' passed full row count validation after failing the fast check.  DBCC UPDATEUSAGE will be automatically initiated.'
  19723.             raiserror (20558, 10, -1, @table_name)
  19724.             DBCC UPDATEUSAGE (0,@qualified_table_name,@min_indid) WITH COUNT_ROWS, NO_INFOMSGS
  19725.             END
  19726.         end
  19727.  
  19728. ALL_DONE:
  19729.  
  19730. -- Give nice message if only generating the expected value:
  19731.  
  19732. -- Msg for rows and checksum:
  19733. -- TEMPORARY:   Remove rowcount string & change message if/when RAISERROR can handle bigint directly.
  19734.  
  19735. SET @rowcount_string = convert(varchar(21),@expected_rowcount)
  19736. if @asked_for_exp_checksum=1 and @asked_for_exp_rows=1 -- Only give message if generating the expected value
  19737.        BEGIN
  19738.     
  19739.        SET @expected_checksum_string = convert(varchar(21), @expected_checksum)
  19740.        -- (20579,10,0,'Generated expected rowcount value of %s and expected checksum value of %s for %s.', 1033)
  19741.     RAISERROR (20579, 10, -1,@rowcount_string,@expected_checksum_string,@table_name)
  19742.        END
  19743.        
  19744. ELSE
  19745.     BEGIN
  19746.         if @asked_for_exp_checksum=0 and @asked_for_exp_rows=1
  19747.         -- Msg (20561,10,0,'Generated expected rowcount value of %s for %s.', 1033)
  19748.         raiserror (20561, 10, -1,@rowcount_string, @table_name)
  19749.     END
  19750.  
  19751.  
  19752. -- Raise error that will shutdown replication agents
  19753. if @shutdown_agent = 1
  19754.     --Msg 20578: 'Shutdown replication agent request.'
  19755.     raiserror (20578, 10, -1)
  19756.     
  19757. return @retstatus
  19758. go
  19759.  
  19760. exec dbo.sp_MS_marksystemobject sp_table_validation
  19761. go
  19762.  
  19763. /* Create  sp_removedbreplication */
  19764. raiserror('Creating procedure sp_removedbreplication', 0,1)
  19765. GO
  19766.  
  19767. /* Permission to sysadmin */
  19768. CREATE PROCEDURE sp_removedbreplication (
  19769.       @dbname     sysname
  19770.     ) AS
  19771.  
  19772.     SET NOCOUNT ON
  19773.  
  19774.     /*
  19775.     ** Declarations.
  19776.     */
  19777.  
  19778.     DECLARE @retcode int
  19779.     DECLARE @proc nvarchar(255)
  19780.     DECLARE @optbit int
  19781.     DECLARE @restoreoverride int
  19782.     /*
  19783.     ** Initialization
  19784.     */
  19785.  
  19786.  
  19787.     /*
  19788.     ** Support override of replication remove on attach and restore
  19789.     */
  19790.  
  19791.     declare @instance sysname
  19792.     declare @regkey nvarchar(260)
  19793.     select @instance = convert(sysname, SERVERPROPERTY('InstanceName'))
  19794.     select @regkey = 'SOFTWARE\Microsoft\'
  19795.     -- default installation
  19796.     if @instance is null
  19797.         SELECT @regkey = @regkey + 'MSSQLServer\Replication' 
  19798.     else
  19799.         SELECT @regkey = @regkey + 'Microsoft SQL Server\' + @instance + '\Replication'
  19800.  
  19801.     SELECT @restoreoverride = 0 -- assume normal remove behavior
  19802.     SELECT @proc = 'master.dbo.xp_regread '
  19803.     EXECUTE @retcode = @proc    'HKEY_LOCAL_MACHINE', 
  19804.                                 @regkey,
  19805.                                 'RestoreOverride',
  19806.                                 @param = @restoreoverride OUTPUT,
  19807.                                 @no_output = 'no_output'
  19808.  
  19809.     IF ( @@error = 0 ) and ( @retcode = 0 )
  19810.     BEGIN
  19811.         -- ReplRestoreOverride = 1 = user elects to take no cleanup on restore or attach
  19812.         IF ( ISNULL( @restoreoverride, 0 ) = 1 )
  19813.             RETURN(0)
  19814.     END
  19815.  
  19816.     /*
  19817.     ** Parameter check
  19818.     ** @dbname
  19819.     */
  19820.     IF NOT EXISTS (SELECT * FROM master.dbo.sysdatabases WHERE
  19821.         name = @dbname collate database_default)
  19822.     BEGIN
  19823.         RAISERROR(15010, 16, -1, @dbname)
  19824.         RETURN(1)
  19825.     END
  19826.  
  19827.     
  19828.     SELECT @proc = quotename(@dbname) + '.dbo.sp_MSremovedbreplication'
  19829.     
  19830.     EXEC @retcode = @proc 
  19831.     IF @@ERROR <> 0 or @retcode <> 0
  19832.     BEGIN
  19833.         return (1)
  19834.     END
  19835.  
  19836.     -- Clear tran bit
  19837.     SELECT @optbit = 1
  19838.     IF EXISTS (SELECT * FROM master..sysdatabases
  19839.         WHERE name = @dbname collate database_default
  19840.         AND (category & @optbit) <> 0)
  19841.     begin
  19842.         /*
  19843.         ** Toggle the category bit in master..sysdatabases
  19844.         */
  19845.         UPDATE master..sysdatabases SET category = category & ~@optbit
  19846.                 WHERE name = @dbname collate database_default
  19847.         IF @@ERROR <> 0 
  19848.         BEGIN
  19849.             return (1)
  19850.         END
  19851.     end
  19852.  
  19853.     -- Clear merge bit
  19854.     SELECT @optbit = 4
  19855.     IF EXISTS (SELECT * FROM master..sysdatabases
  19856.         WHERE name = @dbname collate database_default
  19857.         AND (category & @optbit) <> 0)
  19858.     begin
  19859.         /*
  19860.         ** Toggle the category bit in master..sysdatabases
  19861.         */
  19862.         UPDATE master..sysdatabases SET category = category & ~@optbit
  19863.                 WHERE name = @dbname collate database_default
  19864.         IF @@ERROR <> 0 
  19865.         BEGIN
  19866.             return (1)
  19867.         END
  19868.     end
  19869.  
  19870. GO
  19871.  
  19872. exec dbo.sp_MS_marksystemobject sp_removedbreplication
  19873. go
  19874.  
  19875. raiserror('Creating procedure sp_removesrvreplication', 0,1)
  19876. GO
  19877.  
  19878. create procedure sp_removesrvreplication
  19879. as
  19880. begin
  19881. /* 
  19882.  * unmark replication bits for all servers, databases; used by setup in vupgrade 
  19883.  * assumes override is on; db in single user mode
  19884.  * no need to check rowcounts affected by updates, may not be any repl dbs
  19885.  * failure label avoids repetition of errs if not in single user mode
  19886. */
  19887.  
  19888.     set nocount on 
  19889.  
  19890.     -- server bits
  19891.     declare @srv_distbit int
  19892.     declare @srv_pubbit int
  19893.     declare @srv_subbit int
  19894.     declare @srv_dsnbit int
  19895.  
  19896.     select @srv_distbit = 8, @srv_pubbit = 16, @srv_subbit = 4, @srv_dsnbit = 32 -- dsn subscriber
  19897.  
  19898.     -- db bits
  19899.     declare @db_tranbit int
  19900.     declare @db_mergbit int
  19901.     declare @db_distbit int
  19902.  
  19903.     select @db_tranbit = 1, @db_mergbit = 4, @db_distbit = 16
  19904.  
  19905.     -- setup attach overrides removedb option
  19906.     declare @dbname sysname
  19907.  
  19908.     declare cur_db CURSOR LOCAL FAST_FORWARD for 
  19909.         select name from master..sysdatabases where name <> N'master' collate database_default
  19910.         for read only
  19911.     open cur_db
  19912.     fetch cur_db into @dbname
  19913.     while ( @@fetch_status <> -1 )
  19914.     begin
  19915.         exec dbo.sp_removedbreplication @dbname
  19916.         -- clean up system tables
  19917.         exec ( @dbname + '.dbo.sp_MSdrop_pub_tables' )
  19918.         exec ( @dbname + '.dbo.sp_MSdrop_mergesystables' )
  19919.         fetch next from cur_db into @dbname
  19920.     end
  19921.     close cur_db
  19922.     deallocate cur_db
  19923.  
  19924.     -- unmark db bits
  19925.     -- select name, category from sysdatabases where category & @tranbit = @tranbit 
  19926.     update master..sysdatabases set category = category & ~@db_tranbit where category & @db_tranbit = @db_tranbit
  19927.     if @@ERROR <> 0
  19928.         goto fail
  19929.  
  19930.     update master..sysdatabases set category = category & ~@db_mergbit where category & @db_mergbit = @db_mergbit
  19931.     if @@ERROR <> 0
  19932.         goto fail
  19933.  
  19934.     -- clean up old dist db bit
  19935.     update master..sysdatabases set category = category & ~@db_distbit where category & @db_distbit = @db_distbit
  19936.     if @@ERROR <> 0
  19937.         goto fail
  19938.  
  19939.     -- unmark srv bits (srvstatus = @dsnbit no longer used by replication subscribers but by server )
  19940.     -- select name, srvstatus from sysservers where srvstatus & @srv_distbit = @srv_distbit
  19941.     update master..sysservers set srvstatus = srvstatus & ~@srv_subbit where srvstatus & @srv_subbit = @srv_subbit
  19942.     if @@ERROR <> 0
  19943.         goto fail
  19944.  
  19945.     update master..sysservers set srvstatus = srvstatus & ~@srv_pubbit where srvstatus & @srv_pubbit = @srv_pubbit
  19946.     if @@ERROR <> 0
  19947.         goto fail
  19948.  
  19949.     update master..sysservers set srvstatus = srvstatus & ~@srv_distbit where srvstatus & @srv_distbit = @srv_distbit
  19950.     if @@ERROR <> 0
  19951.         goto fail
  19952.  
  19953.     return (0)
  19954.  
  19955. fail:
  19956. -- ad hoc updates not allowed and not single user
  19957. return (1)
  19958.  
  19959. end
  19960. go
  19961.  
  19962. exec dbo.sp_MS_marksystemobject sp_removesrvreplication
  19963. go
  19964.  
  19965. raiserror('Creating procedure sp_MSremovedbreplication', 0,1)
  19966. GO
  19967.  
  19968. CREATE PROCEDURE sp_MSremovedbreplication
  19969.     AS
  19970.  
  19971.     SET NOCOUNT ON
  19972.  
  19973.     /*
  19974.     ** Declarations.
  19975.     */
  19976.  
  19977.     DECLARE @retcode int
  19978.  
  19979.     -- If the attach info table exists, we need to restore the subscriptions, not
  19980.     -- deleting anything. Do nothing.
  19981.     if exists (select * from sysobjects where
  19982.         name = 'MSreplication_restore_stage')
  19983.         return 0
  19984.  
  19985.     if exists (select * from sysobjects where name = 'sysarticles')
  19986.     -- clean up transactional 
  19987.     begin
  19988.         if not exists (select * from master..MSreplication_options
  19989.             where optname = 'transactional')
  19990.         begin
  19991.             RAISERROR(21027, 16, -1, 'transactional')
  19992.             return(1)
  19993.         end
  19994.     
  19995.         
  19996.         EXEC @retcode = dbo.sp_MSpublishdb @value = 'false',
  19997.             @ignore_distributor = 1
  19998.         IF @@ERROR <> 0 or @retcode <> 0
  19999.         BEGIN
  20000.             return (1)
  20001.         END
  20002.     end
  20003.  
  20004.     if exists (select * from sysobjects where name = 'sysmergearticles')
  20005.     -- clean up merge
  20006.     -- can not use sp_MSmergepublishdb or sp_dropmergepullsubscriptions
  20007.     -- since they depend on serverid and dbname
  20008.     begin
  20009.         declare @pubid uniqueidentifier
  20010.         declare @artid uniqueidentifier
  20011.         declare hC CURSOR LOCAL FAST_FORWARD FOR select DISTINCT pubid, artid FROM 
  20012.             sysmergearticles
  20013.         FOR READ ONLY       
  20014.  
  20015.         OPEN hC
  20016.         FETCH hC INTO @pubid, @artid
  20017.         WHILE (@@fetch_status <> -1)
  20018.         begin
  20019.  
  20020.             EXEC @retcode = dbo.sp_MSarticlecleanup
  20021.                 @pubid, @artid
  20022.             IF @@ERROR <> 0 or @retcode <> 0
  20023.             BEGIN
  20024.                 return (1)
  20025.             end
  20026.             FETCH hC INTO @pubid, @artid
  20027.         end
  20028.  
  20029.         execute @retcode = dbo.sp_MSdrop_mergesystables
  20030.         if @@ERROR <> 0 or @retcode <> 0
  20031.         begin
  20032.                 return (1)
  20033.         end
  20034.     end
  20035.  
  20036.  
  20037.     if exists (select * from sysobjects where name = 'MSreplication_subscriptions')
  20038.     -- clean up tran sub
  20039.     begin
  20040.         -- drop pull subscription
  20041.         EXEC @retcode = dbo.sp_droppullsubscription
  20042.             @publisher = N'all', 
  20043.             @publisher_db = N'all', 
  20044.             @publication = N'all'
  20045.         IF @@ERROR <> 0 or @retcode <> 0
  20046.         BEGIN
  20047.             return (1)
  20048.         END
  20049.  
  20050.         -- drop push subscription
  20051.         EXEC @retcode = dbo.sp_subscription_cleanup
  20052.             @publisher = N'all', 
  20053.             @publisher_db = N'all', 
  20054.             @publication = N'all',
  20055.             @reserved = 'drop_all'
  20056.         IF @@ERROR <> 0 or @retcode <> 0
  20057.         BEGIN
  20058.             return (1)
  20059.         END
  20060.     end
  20061.     
  20062. GO
  20063.  
  20064. exec dbo.sp_MS_marksystemobject sp_MSremovedbreplication
  20065. go
  20066.  
  20067. raiserror('Creating procedure sp_vupgrade_subscription_databases', 0,1)
  20068. GO
  20069. create procedure sp_vupgrade_subscription_databases
  20070. as
  20071. begin
  20072. /* 
  20073.  * Process schema and metadata changes common to all databases. This proc loops
  20074.  * through each database and upgrades MSsubscription_properties, transactional tables
  20075.  * and merge tables.
  20076.  *
  20077.  * Setup version upgrade procedure call order:
  20078.  *    sp_vupgrade_replication -> sp_vupgrade_subscription_databases
  20079. */
  20080.     set nocount on
  20081.  
  20082.     -- raiserror('sp_vupgrade_subscription_databases', 0,1) with nowait
  20083.     declare @dbname nvarchar(270), @has_dbaccess bit
  20084.  
  20085.     declare current_db CURSOR LOCAL FAST_FORWARD for 
  20086.         select N'[' + replace(name, N']', N']]') + N']', has_dbaccess(name) from master..sysdatabases 
  20087.             WHERE name <> N'master' collate database_default
  20088.             AND name <> N'tempdb' collate database_default
  20089.             AND name <> N'msdb' collate database_default
  20090.         for read only
  20091.  
  20092.     -- Note: dbname is quoted!
  20093.     open current_db
  20094.     fetch current_db into @dbname, @has_dbaccess
  20095.     while ( @@fetch_status <> -1 )
  20096.     begin
  20097.  
  20098.         -- upgrade repl tables in sub dbs if needed - sub dbs are not marked with subscribed status 
  20099.         -- skip any database in an offline state and write warning to upgrade log
  20100.         if ( @has_dbaccess = 1 )
  20101.         begin
  20102.             --
  20103.             -- NOTE : there are several things to process here
  20104.             -- for each upgrade - all these steps may NOT be necessary
  20105.             -- and should be commented/uncommented out as required
  20106.             -- 
  20107.             -- Current setting for SQL 2000 SP1 upgrade
  20108.             --
  20109.             raiserror( 21377, 0, 1, @dbname) with nowait
  20110.             -- exec ('use '+ @dbname + ' exec dbo.sp_vupgrade_MSsubscription_properties')
  20111.             exec ('use '+ @dbname + ' exec dbo.sp_vupgrade_subscription_tables')
  20112.             exec ('use '+ @dbname + ' exec dbo.sp_vupgrade_mergetables')
  20113.             -- exec ('use '+ @dbname + ' exec dbo.sp_vupgrade_subpass')
  20114.         end
  20115.         else
  20116.         begin
  20117.             raiserror( 21373, 10, 1, @dbname) with nowait
  20118.         end
  20119.  
  20120.         fetch next from current_db into @dbname, @has_dbaccess
  20121.     end
  20122.     close current_db
  20123.     deallocate current_db
  20124. end
  20125. go
  20126.  
  20127. raiserror('Creating procedure sp_MScopyregvalue', 0,1)
  20128. GO
  20129. create procedure sp_MScopyregvalue(    
  20130.     @oldregkey            nvarchar(1000),
  20131.     @newregkey            nvarchar(1000),
  20132.     @param_type            nvarchar(20),
  20133.     @param_name            sysname)
  20134. as
  20135.     set nocount on
  20136.     declare @retcode     int
  20137.     create table #binaryvalues ( value sysname collate database_default, data varbinary(256))
  20138.     if (@param_type = 'REG_SZ')
  20139.         begin
  20140.             declare @value_str nvarchar(1000)
  20141.             set @value_str = NULL
  20142.             -- Read value from old reg location and write to new one
  20143.             EXECUTE @retcode = master.dbo.xp_regread 'HKEY_LOCAL_MACHINE',
  20144.                                    @oldregkey,
  20145.                                    @param_name,
  20146.                                    @param = @value_str OUTPUT,
  20147.                                    @no_output = 'no_output'
  20148.             if @retcode <> 0 or @@ERROR <> 0
  20149.                 begin
  20150.                     set @retcode = 0
  20151.                     goto FAILURE
  20152.                 end                
  20153.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  20154.                                @newregkey,
  20155.                                @param_name,
  20156.                             'REG_SZ',
  20157.                                @value_str
  20158.             if @retcode <> 0 OR @@ERROR <> 0
  20159.             begin
  20160.                 set @retcode = 1
  20161.                 goto FAILURE
  20162.             end                
  20163.         end
  20164.     if (@param_type = 'REG_DWORD')
  20165.         begin
  20166.             declare @value_int int
  20167.             set @value_int = NULL
  20168.             -- Read value from old reg location and write to new one
  20169.             EXECUTE @retcode = master.dbo.xp_regread 'HKEY_LOCAL_MACHINE',
  20170.                                    @oldregkey,
  20171.                                    @param_name,
  20172.                                    @param = @value_int OUTPUT,
  20173.                                    @no_output = 'no_output'
  20174.             if @retcode <> 0 or @@ERROR <> 0
  20175.                 begin
  20176.                     set @retcode = 0
  20177.                     goto FAILURE
  20178.                 end                
  20179.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  20180.                                @newregkey,
  20181.                                @param_name,
  20182.                             'REG_DWORD',
  20183.                                @value_int
  20184.             if @retcode <> 0 OR @@ERROR <> 0
  20185.             begin
  20186.                 set @retcode = 1
  20187.                 goto FAILURE
  20188.             end
  20189.         end
  20190.     if (@param_type = 'REG_BINARY')
  20191.         begin
  20192.             declare @value_binary varbinary(256)
  20193.             set @value_binary = NULL
  20194.             -- Read value from old reg location and write to new one
  20195. /*
  20196.     -- binary output buffer was corrupted for a couple of builds;looks to be working now
  20197.     -- if reverting to this read, must pre-check exists on regkey to avoid regopenkey failure 
  20198.     -- on non-existent key when no OUTPUT parm specified
  20199.             insert into #binaryvalues EXECUTE master.dbo.xp_regread 'HKEY_LOCAL_MACHINE',
  20200.                                    @oldregkey,
  20201.                                    @param_name
  20202.             if @@ERROR <> 0
  20203.                 begin
  20204.                     set @retcode = 0
  20205.                     goto FAILURE
  20206.                 end        
  20207.             select @value_binary = data from #binaryvalues
  20208.             if @value_binary is NOT NULL
  20209.                 EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  20210.                                    @newregkey,
  20211.                                    @param_name,
  20212.                                 'REG_BINARY',
  20213.                                    @value_binary
  20214.                                    
  20215. */
  20216.             EXECUTE @retcode = master.dbo.xp_regread 'HKEY_LOCAL_MACHINE',
  20217.                                    @oldregkey,
  20218.                                    @param_name,
  20219.                                    @param = @value_binary OUTPUT,
  20220.                                    @no_output = 'no_output'
  20221.             if @retcode <> 0 or @@ERROR <> 0
  20222.                 begin
  20223.                     set @retcode = 0
  20224.                     goto FAILURE
  20225.                 end                
  20226.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  20227.                                @newregkey,
  20228.                                @param_name,
  20229.                             'REG_BINARY',
  20230.                                @value_binary
  20231.             if @retcode <> 0 OR @@ERROR <> 0
  20232.                 begin
  20233.                     set @retcode = 1
  20234.                     goto FAILURE
  20235.                 end
  20236.         end
  20237.     set @retcode = 0
  20238. FAILURE:
  20239.     drop table #binaryvalues
  20240.     return @retcode
  20241. go
  20242.  
  20243. raiserror('Creating procedure sp_vupgrade_registry', 0,1)
  20244. GO
  20245. create procedure sp_vupgrade_registry
  20246. as
  20247.     set nocount on
  20248.     declare @oldregkey                        nvarchar(1000)
  20249.     declare @newregkey                        nvarchar(1000)
  20250.     declare @subscription_name                nvarchar(1000)
  20251.     declare @resolver_name                    nvarchar(1000)
  20252.     declare @resolver_clsid                    nvarchar(1000)
  20253.     declare @retcode                        int
  20254.     declare @keyexist                         int
  20255.     
  20256.     -- raiserror('sp_vupgrade_registry', 0,1)
  20257.     
  20258.     create table #keyexist (keyexist int)
  20259.  
  20260.     set @oldregkey = 'SOFTWARE\Microsoft\MSSQLServer\Replication\Subscriptions\'
  20261.     insert into #keyexist EXECUTE master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', @oldregkey
  20262.     select @keyexist = keyexist from #keyexist
  20263.  
  20264.     if @keyexist = 1
  20265.     begin
  20266.         -- Move the registered subscriptions to new location in registry
  20267.         create table #syncmgr_subscriptions (subscription_name nvarchar(1000) collate database_default)
  20268.         set @oldregkey = 'SOFTWARE\Microsoft\MSSQLServer\Replication\Subscriptions\'
  20269.         insert into #syncmgr_subscriptions EXECUTE master.dbo.xp_regenumkeys 'HKEY_LOCAL_MACHINE', @oldregkey
  20270.         declare #subscriptioncursor CURSOR LOCAL FAST_FORWARD FOR 
  20271.             select DISTINCT subscription_name
  20272.                    FROM #syncmgr_subscriptions    FOR READ ONLY
  20273.  
  20274.         open #subscriptioncursor
  20275.         fetch next from #subscriptioncursor into @subscription_name
  20276.         while (@@fetch_status <> -1)
  20277.         begin
  20278.  
  20279.             set @newregkey = 'SOFTWARE\Microsoft\Microsoft SQL Server\80\Replication\Subscriptions\' + @subscription_name
  20280.             set @oldregkey = 'SOFTWARE\Microsoft\MSSQLServer\Replication\Subscriptions\' + @subscription_name
  20281.  
  20282.             delete from #keyexist
  20283.             insert into #keyexist EXECUTE master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', @oldregkey
  20284.             select @keyexist = keyexist from #keyexist
  20285.             if @keyexist = 1
  20286.                 begin
  20287.  
  20288.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'ProfileName'        
  20289.                     if @retcode <> 0
  20290.                         begin
  20291.                             set @retcode = 1
  20292.                             goto FAILURE
  20293.                         end                
  20294.  
  20295.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'HostName'        
  20296.                     if @retcode <> 0
  20297.                         begin
  20298.                             set @retcode = 1
  20299.                             goto FAILURE
  20300.                         end                
  20301.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_DWORD', 'ReplicationType'        
  20302.                     if @retcode <> 0
  20303.                         begin
  20304.                             set @retcode = 1
  20305.                             goto FAILURE
  20306.                         end                
  20307.  
  20308.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_DWORD', 'SubscriptionType'        
  20309.                     if @retcode <> 0
  20310.                         begin
  20311.                             set @retcode = 1
  20312.                             goto FAILURE
  20313.                         end                
  20314.  
  20315.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_DWORD', 'ExchangeType'        
  20316.                     if @retcode <> 0
  20317.                         begin
  20318.                             set @retcode = 1
  20319.                             goto FAILURE
  20320.                         end                
  20321.  
  20322.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_DWORD', 'Validate'        
  20323.                     if @retcode <> 0
  20324.                         begin
  20325.                             set @retcode = 1
  20326.                             goto FAILURE
  20327.                         end                
  20328.  
  20329.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_DWORD', 'LoginTimeout'        
  20330.                     if @retcode <> 0
  20331.                         begin
  20332.                             set @retcode = 1
  20333.                             goto FAILURE
  20334.                         end                
  20335.  
  20336.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_DWORD', 'QueryTimeout'        
  20337.                     if @retcode <> 0
  20338.                         begin
  20339.                             set @retcode = 1
  20340.                             goto FAILURE
  20341.                         end                
  20342.  
  20343.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'SubscriptionName'        
  20344.                     if @retcode <> 0
  20345.                         begin
  20346.                             set @retcode = 1
  20347.                             goto FAILURE
  20348.                         end                
  20349.  
  20350.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_BINARY', 'LastUpdateTime'        
  20351.                     if @retcode <> 0
  20352.                         begin
  20353.                             set @retcode = 1
  20354.                             goto FAILURE
  20355.                         end                
  20356.  
  20357.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'Subid'        
  20358.                     if @retcode <> 0
  20359.                         begin
  20360.                             set @retcode = 1
  20361.                             goto FAILURE
  20362.                         end                
  20363.  
  20364.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'Publication'        
  20365.                     if @retcode <> 0
  20366.                         begin
  20367.                             set @retcode = 1
  20368.                             goto FAILURE
  20369.                         end                
  20370.  
  20371.  
  20372.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'Publisher'        
  20373.                     if @retcode <> 0
  20374.                         begin
  20375.                             set @retcode = 1
  20376.                             goto FAILURE
  20377.                         end                
  20378.  
  20379.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'PublisherDb'        
  20380.                     if @retcode <> 0
  20381.                         begin
  20382.                             set @retcode = 1
  20383.                             goto FAILURE
  20384.                         end                
  20385.  
  20386.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_DWORD', 'PublisherSecurityMode'        
  20387.                     if @retcode <> 0
  20388.                         begin
  20389.                             set @retcode = 1
  20390.                             goto FAILURE
  20391.                         end                
  20392.  
  20393.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'PublisherLogin'        
  20394.                     if @retcode <> 0
  20395.                         begin
  20396.                             set @retcode = 1
  20397.                             goto FAILURE
  20398.                         end                
  20399.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'PublisherEncryptedPassword'        
  20400.                     if @retcode <> 0
  20401.                         begin
  20402.                             set @retcode = 1
  20403.                             goto FAILURE
  20404.                         end                
  20405.  
  20406.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_BINARY', 'PublisherEncryptedPasswordBinary'        
  20407.                     if @retcode <> 0
  20408.                         begin
  20409.                             set @retcode = 1
  20410.                             goto FAILURE
  20411.                         end                
  20412.  
  20413.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'PublisherAddress'        
  20414.                     if @retcode <> 0
  20415.                         begin
  20416.                             set @retcode = 1
  20417.                             goto FAILURE
  20418.                         end                
  20419.  
  20420.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'PublisherNetwork'        
  20421.                     if @retcode <> 0
  20422.                         begin
  20423.                             set @retcode = 1
  20424.                             goto FAILURE
  20425.                         end    
  20426.  
  20427.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'Subscriber'        
  20428.                     if @retcode <> 0
  20429.                         begin
  20430.                             set @retcode = 1
  20431.                             goto FAILURE
  20432.                         end                
  20433.  
  20434.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'SubscriberDb'        
  20435.                     if @retcode <> 0
  20436.                         begin
  20437.                             set @retcode = 1
  20438.                             goto FAILURE
  20439.                         end                
  20440.  
  20441.  
  20442.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_DWORD', 'SubscriberSecurityMode'        
  20443.                     if @retcode <> 0
  20444.                         begin
  20445.                             set @retcode = 1
  20446.                             goto FAILURE
  20447.                         end                
  20448.  
  20449.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'SubscriberLogin'        
  20450.                     if @retcode <> 0
  20451.                         begin
  20452.                             set @retcode = 1
  20453.                             goto FAILURE
  20454.                         end                
  20455.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'SubscriberEncryptedPassword'        
  20456.                     if @retcode <> 0
  20457.                         begin
  20458.                             set @retcode = 1
  20459.                             goto FAILURE
  20460.                         end                
  20461.  
  20462.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_BINARY', 'SubscriberEncryptedPasswordBinary'        
  20463.                     if @retcode <> 0
  20464.                         begin
  20465.                             set @retcode = 1
  20466.                             goto FAILURE
  20467.                         end                
  20468.  
  20469.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_DWORD', 'SubscriberDatasourceType'        
  20470.                     if @retcode <> 0
  20471.                         begin
  20472.                             set @retcode = 1
  20473.                             goto FAILURE
  20474.                         end                
  20475.  
  20476.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'SubscriberDatabasePath'        
  20477.                     if @retcode <> 0
  20478.                         begin
  20479.                             set @retcode = 1
  20480.                             goto FAILURE
  20481.                         end                
  20482.  
  20483.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'Distributor'        
  20484.                     if @retcode <> 0
  20485.                         begin
  20486.                             set @retcode = 1
  20487.                             goto FAILURE
  20488.                         end                
  20489.  
  20490.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_DWORD', 'DistributorSecurityMode'        
  20491.                     if @retcode <> 0
  20492.                         begin
  20493.                             set @retcode = 1
  20494.                             goto FAILURE
  20495.                         end                
  20496.  
  20497.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'DistributorLogin'        
  20498.                     if @retcode <> 0
  20499.                         begin
  20500.                             set @retcode = 1
  20501.                             goto FAILURE
  20502.                         end                
  20503.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'DistributorEncryptedPassword'        
  20504.                     if @retcode <> 0
  20505.                         begin
  20506.                             set @retcode = 1
  20507.                             goto FAILURE
  20508.                         end                
  20509.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_BINARY', 'DistributorEncryptedPasswordBinary'        
  20510.                     if @retcode <> 0
  20511.                         begin
  20512.                             set @retcode = 1
  20513.                             goto FAILURE
  20514.                         end                
  20515.  
  20516.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'DistributorAddress'        
  20517.                     if @retcode <> 0
  20518.                         begin
  20519.                             set @retcode = 1
  20520.                             goto FAILURE
  20521.                         end                
  20522.  
  20523.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'DistributorNetwork'        
  20524.                     if @retcode <> 0
  20525.                         begin
  20526.                             set @retcode = 1
  20527.                             goto FAILURE
  20528.                         end    
  20529.  
  20530.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_DWORD', 'UseInteractiveResolver'        
  20531.                     if @retcode <> 0
  20532.                         begin
  20533.                             set @retcode = 1
  20534.                             goto FAILURE
  20535.                         end    
  20536.  
  20537.                     -- regdelete returns 'Access Denied' message if key does not exist; check before delete
  20538.                     delete from #keyexist
  20539.                     insert into #keyexist EXECUTE master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', @oldregkey
  20540.                     select @keyexist = keyexist from #keyexist
  20541.                     if @keyexist = 1
  20542.                     begin
  20543.                         exec @retcode = master.dbo.xp_regdeletekey 'HKEY_LOCAL_MACHINE', @oldregkey
  20544.                         if @@error <> 0 OR @retcode <> 0
  20545.                         begin
  20546.                             set @retcode = 1
  20547.                             goto FAILURE
  20548.                         end                
  20549.                     end
  20550.                 end
  20551.             fetch next from #subscriptioncursor into @subscription_name
  20552.         end
  20553.  
  20554.         close #subscriptioncursor
  20555.         deallocate #subscriptioncursor
  20556.         drop table #syncmgr_subscriptions 
  20557.  
  20558.         -- done moving reg keys/values.  delete old key; check key exists before delete
  20559.         set @oldregkey = 'SOFTWARE\Microsoft\MSSQLServer\Replication\Subscriptions\'
  20560.         delete from #keyexist
  20561.         insert into #keyexist EXECUTE master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', @oldregkey
  20562.         select @keyexist = keyexist from #keyexist
  20563.         if @keyexist = 1
  20564.         begin
  20565.             exec @retcode = master.dbo.xp_regdeletekey 'HKEY_LOCAL_MACHINE', @oldregkey
  20566.             if @@error <> 0 OR @retcode <> 0
  20567.             begin
  20568.                 set @retcode = 1
  20569.                 goto FAILURE
  20570.             end
  20571.         end                
  20572.     end            
  20573.  
  20574.     -- Move the registered article resolvers to new location in registry
  20575.     set @oldregkey = 'SOFTWARE\Microsoft\MSSQLServer\Replication\ArticleResolver'
  20576.     set @newregkey = 'SOFTWARE\Microsoft\Microsoft SQL Server\80\Replication\ArticleResolver' 
  20577.     delete from #keyexist
  20578.     insert into #keyexist EXECUTE master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', @oldregkey
  20579.     select @keyexist = keyexist from #keyexist
  20580.     if @keyexist = 1
  20581.         begin
  20582.  
  20583.             create table #article_resolvers (resolver_name nvarchar(1000) collate database_default, resolver_clsid nvarchar(1000))
  20584.             insert into #article_resolvers EXECUTE master.dbo.xp_regenumvalues 'HKEY_LOCAL_MACHINE', @oldregkey
  20585.             declare #resolvercursor CURSOR LOCAL FAST_FORWARD FOR 
  20586.                 select DISTINCT resolver_name, resolver_clsid
  20587.                        FROM #article_resolvers
  20588.                     FOR READ ONLY
  20589.  
  20590.             open #resolvercursor
  20591.             fetch next from #resolvercursor into @resolver_name, @resolver_clsid
  20592.             while (@@fetch_status <> -1)
  20593.             begin
  20594.                 exec @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE', @newregkey, @resolver_name, 'REG_SZ', @resolver_clsid
  20595.                 if @retcode <> 0 OR @@ERROR <> 0
  20596.                     begin
  20597.                         set @retcode = 1
  20598.                         goto FAILURE
  20599.                     end                
  20600.                 fetch next from #resolvercursor into @resolver_name, @resolver_clsid
  20601.             end
  20602.  
  20603.             -- done moving reg keys/values.  delete old key 
  20604.             exec @retcode = master.dbo.xp_regdeletekey 'HKEY_LOCAL_MACHINE', @oldregkey
  20605.             if @@error <> 0 OR @retcode <> 0
  20606.             begin
  20607.                 set @retcode = 1
  20608.                 goto FAILURE
  20609.             end                
  20610.             close #resolvercursor
  20611.             deallocate #resolvercursor
  20612.             drop table #article_resolvers 
  20613.         end
  20614.     set @retcode = 0
  20615. FAILURE:
  20616.     drop table #keyexist
  20617.     return @retcode
  20618.  
  20619. go
  20620. exec dbo.sp_MS_marksystemobject sp_vupgrade_registry
  20621. go
  20622.  
  20623. raiserror('Creating procedure sp_vupgrade_subscription_tables', 0,1)
  20624. GO
  20625. create procedure sp_vupgrade_subscription_tables
  20626. as
  20627. begin
  20628. /* 
  20629.  * Process schema and metadata changes common to transactional pub/sub databases. Exception is creation
  20630.  * of MSrepl_identity_range table needed for tran and merge publishing databases and merge subscr db's.
  20631.  *
  20632.  * Setup version upgrade procedure call order:
  20633.  *    sp_vupgrade_replication -> sp_vupgrade_subscription_databases -> sp_vupgrade_subscription_tables
  20634. */
  20635.  
  20636.     -- raiserror('sp_vupgrade_subscription_tables', 0,1) with nowait
  20637.  
  20638.     set nocount on 
  20639.  
  20640.     DECLARE @table_name sysname
  20641.     declare @retcode int
  20642.  
  20643.     -- Identity range management; create in  publishing databases
  20644.     if exists (select * from sysobjects where name = 'sysarticles')
  20645.     begin
  20646.         if not exists (select * from sysobjects where name = 'MSpub_identity_range')
  20647.         begin        
  20648.             CREATE TABLE dbo.MSpub_identity_range
  20649.             (
  20650.                 objid int not null,
  20651.                 range bigint not null,
  20652.                 pub_range bigint not null,
  20653.                 current_pub_range bigint not null,
  20654.                 threshold int not null,
  20655.                 last_seed bigint null -- It will be not when uninitialized.
  20656.             )     
  20657.  
  20658.             IF @@ERROR <> 0
  20659.             BEGIN
  20660.                 return(1)
  20661.             END
  20662.  
  20663.             -- mark the index as a system object
  20664.             exec dbo.sp_MS_marksystemobject 'MSpub_identity_range'
  20665.  
  20666.             IF @@ERROR <> 0
  20667.             BEGIN
  20668.                 return(1)
  20669.             END
  20670.  
  20671.             create unique nonclustered index unc1MSpub_identity_range
  20672.                 on MSpub_identity_range (objid)
  20673.  
  20674.             IF @@ERROR <> 0
  20675.             BEGIN
  20676.                 return(1)
  20677.             END
  20678.         end
  20679.     end
  20680.  
  20681.     -- Identity range management; create in all publishing databases and merge subscription databases (Shiloh)
  20682.     if exists (select * from sysobjects where name = 'sysmergearticles')
  20683.     begin
  20684.         if not exists (select * from sysobjects where name = 'MSrepl_identity_range')
  20685.         begin        
  20686.             create table dbo.MSrepl_identity_range (
  20687.                 objid                    int not NULL primary key,
  20688.                 next_seed                bigint NULL, --resource control
  20689.                 pub_range                bigint NULL, --publisher range
  20690.                 range                    bigint NULL, -- set by sp_addmergearticle
  20691.                 max_identity            bigint NULL, --resource control
  20692.                 threshold                int    NULL,    --in percentage, set by sp_addmergearticle
  20693.                 current_max                bigint NULL    --max value for current check constraint,set by sp_addmergearticle
  20694.                 )
  20695.             exec dbo.sp_MS_marksystemobject MSrepl_identity_range
  20696.             if @@ERROR <> 0
  20697.                 return(1)
  20698.             grant select on MSrepl_identity_range to public
  20699.         end
  20700.     end
  20701.  
  20702.     --    Create unique index on tables that did not have one previously. The index is not created
  20703.     --    if duplicates rows exist in the table. 
  20704.  
  20705.     --    MSreplication_subscriptions (SQL7.0 SP1)
  20706.     SELECT @table_name = N'MSreplication_subscriptions'
  20707.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSreplication_subscriptions' ) or 
  20708.         EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSsubscription_agents' )
  20709.     BEGIN
  20710.         IF EXISTS ( SELECT publication, publisher_db, publisher, subscription_type 
  20711.             FROM MSreplication_subscriptions
  20712.             GROUP BY publication, publisher_db, publisher, subscription_type
  20713.             HAVING COUNT(*) > 1 )
  20714.             RAISERROR (21203, 10, 1, @table_name)
  20715.         ELSE
  20716.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'uc1MSReplication_subscriptions' AND
  20717.                 id = OBJECT_ID('MSreplication_subscriptions') )
  20718.                 CREATE UNIQUE CLUSTERED INDEX uc1MSReplication_subscriptions ON
  20719.                 MSreplication_subscriptions(publication, publisher_db, publisher, subscription_type)
  20720.         
  20721.         -- Create MSsubscription_agents table 
  20722.         exec @retcode = dbo.sp_MScreate_sub_tables
  20723.             @tran_sub_table = 1,
  20724.             @property_table = 0,
  20725.             @sqlqueue_table = 0
  20726.         IF @@ERROR <> 0 or @retcode <> 0
  20727.             RETURN(1)
  20728.  
  20729.         -- Add new columns to MSsubscription_agents, for 8.0 pre beta upgrade.
  20730.  
  20731.         -- status of the last sync (Shiloh)
  20732.         if not exists (select * from syscolumns where id = object_id('MSsubscription_agents') and
  20733.                             name = 'last_sync_status')
  20734.         begin
  20735.                 alter table MSsubscription_agents add last_sync_status int NULL
  20736.                 if @@ERROR <> 0
  20737.                     return 1
  20738.         end
  20739.  
  20740.         -- summary message of the last sync (Shiloh)
  20741.         if not exists (select * from syscolumns where id = object_id('MSsubscription_agents') and
  20742.                             name = 'last_sync_summary')
  20743.         begin
  20744.                 alter table MSsubscription_agents add last_sync_summary sysname NULL
  20745.                 if @@ERROR <> 0
  20746.                     return 1
  20747.         end
  20748.  
  20749.         -- summary message of the last sync (Shiloh)
  20750.         if not exists (select * from syscolumns where id = object_id('MSsubscription_agents') and
  20751.                             name = 'last_sync_time')
  20752.         begin
  20753.                 alter table MSsubscription_agents add last_sync_time datetime NULL
  20754.                 if @@ERROR <> 0
  20755.                     return 1
  20756.         end
  20757.     END
  20758.  
  20759.     --    MSreplication_objects (SQL7.0 SP1)
  20760.     SELECT @table_name = N'MSreplication_objects'
  20761.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSreplication_objects' ) 
  20762.     BEGIN
  20763.         IF EXISTS ( SELECT object_name
  20764.             FROM MSreplication_objects
  20765.             GROUP BY object_name
  20766.             HAVING COUNT(*) > 1 )
  20767.             RAISERROR (21203, 10, 3, @table_name)
  20768.         ELSE    
  20769.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'ucMSreplication_objects' AND
  20770.                 id = OBJECT_ID('MSreplication_objects') )
  20771.                 CREATE UNIQUE CLUSTERED INDEX ucMSreplication_objects ON dbo.MSreplication_objects(object_name)
  20772.     END
  20773.  
  20774.     --    MSreplication_queue (SQL2000 SP3)
  20775.     SELECT @table_name = N'MSreplication_queue'
  20776.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = @table_name ) 
  20777.     BEGIN
  20778.         exec @retcode = sp_MScreate_sub_tables
  20779.             @tran_sub_table = 0,
  20780.             @property_table = 0,
  20781.             @sqlqueue_table = 1
  20782.         IF @@ERROR <> 0 or @retcode <> 0
  20783.             RETURN(1)
  20784.     END
  20785.  
  20786.     --    MSrepl_queuedtraninfo (SQL2000 SP3)
  20787.     SELECT @table_name = N'MSrepl_queuedtraninfo'
  20788.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = @table_name ) 
  20789.     BEGIN
  20790.         exec @retcode = sp_MScreate_sub_tables
  20791.             @tran_sub_table = 0,
  20792.             @property_table = 0,
  20793.             @sqlqueue_table = 1
  20794.         IF @@ERROR <> 0 or @retcode <> 0
  20795.             RETURN(1)
  20796.     END
  20797.  
  20798. end
  20799. go
  20800.  
  20801. exec dbo.sp_MS_marksystemobject sp_vupgrade_subscription_tables
  20802. go
  20803.  
  20804. raiserror('Creating procedure sp_vupgrade_mergetables', 0,1)
  20805. GO
  20806. create procedure sp_vupgrade_mergetables( @skip_procgen bit = 0 )
  20807. as
  20808. begin
  20809. /* 
  20810.  * Process schema and metadata changes common to transactional pub/sub databases.
  20811.  *
  20812.  * @skip_procgen is set by sp_restoredbreplication when calling this proc directly to update
  20813.  * system tables during restore of a down-level (e.g. - SQL7.0) database to current version
  20814.  * 
  20815.  * Setup version upgrade procedure call order:
  20816.  *    sp_vupgrade_replication -> sp_vupgrade_subscription_databases -> sp_vupgrade_mergetables
  20817. */
  20818.  
  20819.     set nocount on 
  20820.  
  20821.     declare @artnick int
  20822.     declare @objid  int
  20823.     declare @col_track int
  20824.     declare @article sysname
  20825.     declare @pubname sysname
  20826.     declare @artid uniqueidentifier
  20827.     declare @pubid uniqueidentifier
  20828.     declare @qualified_name         nvarchar(257)
  20829.     declare @source_owner           sysname
  20830.     declare @source_object            sysname
  20831.     declare @table_name                sysname
  20832.     declare @retcode                integer
  20833.     declare @snapshot_ready            int
  20834.     declare @cmd                     nvarchar(4000)
  20835.     declare @distributor sysname
  20836.  
  20837.     -- raiserror('sp_vupgrade_mergetables', 0,1)
  20838.  
  20839.     /*
  20840.      * sysmergearticles
  20841.     */
  20842.     if (exists (select * from sysobjects where name = 'sysmergearticles'))
  20843.     begin
  20844.  
  20845.         -- Set all invalid sysmergearticles.sync_objid to the corresponding 
  20846.         -- objid, this will allow regeneration of article procs to succeed
  20847.         update dbo.sysmergearticles 
  20848.            set sync_objid = objid 
  20849.          where object_name(sync_objid) is null
  20850.  
  20851.         if @@ERROR<>0
  20852.             return(1)
  20853.  
  20854.         exec @retcode = dbo.sp_MSUpgradeConflictTable @skip_procgen
  20855.         if @@ERROR<>0 or @retcode<>0
  20856.             return (1)        
  20857.         if not exists (select * from syscolumns where id = object_id('sysmergearticles') and
  20858.                         name = 'maxversion_at_cleanup')
  20859.         begin
  20860.             alter table sysmergearticles add maxversion_at_cleanup int NOT NULL default 1
  20861.             if @@ERROR <> 0 return 1
  20862.         end
  20863.  
  20864.         if not exists (select * from syscolumns where id = object_id('sysmergearticles') and
  20865.                         name = 'published_in_tran_pub')
  20866.         begin
  20867.             alter table sysmergearticles add published_in_tran_pub bit NOT NULL default 0
  20868.             if @@ERROR <> 0 return 1
  20869.         end
  20870.  
  20871.         if not exists (select * from sysobjects where name = 'sysmergeschemaarticles')
  20872.             begin                
  20873.                 create table dbo.sysmergeschemaarticles 
  20874.                 (   name                    sysname             NOT NULL,
  20875.                     type                    tinyint             NULL,
  20876.                     objid                   int                 NOT NULL,
  20877.                     artid                   uniqueidentifier    NOT NULL,
  20878.                     description             nvarchar(255)       NULL,
  20879.                     pre_creation_command    tinyint             NULL,
  20880.                     pubid                   uniqueidentifier    NOT NULL,
  20881.                     status                  tinyint             NULL,
  20882.                     creation_script         nvarchar(255)       NULL,
  20883.                     schema_option           binary(8)           NULL,
  20884.                     destination_object      sysname             NOT NULL,
  20885.                     destination_owner       sysname             NULL
  20886.                     -- Note: Please update sysmergeextendedarticlesview whenever
  20887.                     -- there is a schema change in sysmergeschemaarticles
  20888.                 )
  20889.                 
  20890.                 exec dbo.sp_MS_marksystemobject sysmergeschemaarticles
  20891.                 create unique clustered index uc1sysmergeschemaarticles on sysmergeschemaarticles(artid, pubid)
  20892.  
  20893.  
  20894.             end
  20895.  
  20896.         if not exists (select * from sysobjects where name = 'MSmerge_errorlineage')
  20897.             begin        
  20898.                 create table dbo.MSmerge_errorlineage (
  20899.                 tablenick        int NOT NULL,
  20900.                 rowguid            uniqueidentifier NOT NULL,
  20901.                 lineage            varbinary(255)
  20902.                 )
  20903.                 exec dbo.sp_MS_marksystemobject MSmerge_errorlineage
  20904.                 create unique clustered index uc1errorlineage on MSmerge_errorlineage(tablenick, rowguid)
  20905.                 
  20906.                 grant select on MSmerge_errorlineage to public
  20907.             end
  20908.  
  20909.         if not exists (select * from sysobjects where name = 'MSmerge_altsyncpartners')
  20910.             begin            
  20911.                 create table dbo.MSmerge_altsyncpartners (
  20912.                     subid                 uniqueidentifier     not null,
  20913.                     alternate_subid     uniqueidentifier     not null,
  20914.                     description            nvarchar(255)        NULL
  20915.  
  20916.                 )
  20917.  
  20918.                 exec dbo.sp_MS_marksystemobject MSmerge_altsyncpartners
  20919.  
  20920.                 create unique clustered index uciMSmerge_altsyncpartners on 
  20921.                     dbo.MSmerge_altsyncpartners(subid, alternate_subid)
  20922.                 
  20923.             end
  20924.  
  20925.  
  20926.         -- create view now that sysmergearticles is altered and sysmergeextendedarticles is created
  20927.         if exists (select * from sysobjects where name='sysmergeextendedarticlesview')
  20928.         begin
  20929.             drop view dbo.sysmergeextendedarticlesview
  20930.         end    
  20931.  
  20932.         -- cannot create view directly in proc
  20933.         exec ('create view dbo.sysmergeextendedarticlesview
  20934.                    as
  20935.                select name, type, objid, sync_objid, view_type, artid, description, pre_creation_command, pubid,
  20936.                nickname, column_tracking, status, conflict_table, creation_script, conflict_script, article_resolver,
  20937.                ins_conflict_proc, insert_proc, update_proc, select_proc, schema_option, destination_object,
  20938.                resolver_clsid, subset_filterclause, missing_col_count, missing_cols, columns, resolver_info,
  20939.                view_sel_proc, gen_cur, excluded_cols, excluded_col_count, vertical_partition, identity_support,
  20940.                destination_owner, before_image_objid, before_view_objid, verify_resolver_signature, 
  20941.                allow_interactive_resolver, fast_multicol_updateproc, check_permissions, maxversion_at_cleanup,
  20942.                published_in_tran_pub                   
  20943.                from sysmergearticles
  20944.                union all
  20945.                select name, type, objid, NULL, NULL, artid, description, pre_creation_command, pubid, 
  20946.                NULL, NULL, status, NULL, creation_script, NULL, NULL, 
  20947.                NULL, NULL, NULL, NULL, schema_option, destination_object, 
  20948.                NULL, NULL, NULL, NULL, NULL, NULL, 
  20949.                NULL, NULL, NULL, NULL, NULL, NULL, 
  20950.                destination_owner, NULL, NULL, NULL, 
  20951.                0, 0, 0, NULL, 0
  20952.                from sysmergeschemaarticles
  20953.                go')
  20954.  
  20955.         exec dbo.sp_MS_marksystemobject sysmergeextendedarticlesview
  20956.  
  20957.         -- Do not regenerate views, procs if this is called from sp_restoredbreplication. Restore only
  20958.         -- needs to update schema, then it can call existing system procs to remove db replication cleanly
  20959.         if @skip_procgen = 0
  20960.         begin
  20961.             select @artnick = min(a.nickname) from sysmergearticles a inner join sysmergepublications p on p.pubid = a.pubid where p.snapshot_ready =1
  20962.             while @artnick is not null
  20963.             begin
  20964.                 -- find base table to compute number of columns
  20965.                 select @objid = objid, @col_track = column_tracking
  20966.                     from sysmergearticles where nickname = @artnick
  20967.  
  20968.                 -- regenerate the triggers
  20969.                 select @source_owner = user_name(uid), @source_object = name from sysobjects where id = @objid
  20970.                 select @qualified_name = QUOTENAME(@source_owner) + '.' + QUOTENAME(@source_object)
  20971.                 exec dbo.sp_MSaddmergetriggers @qualified_name, NULL, @col_track
  20972.  
  20973.                 /* Loop through all articles that this table is involved in and regenerate the article procs */
  20974.                 declare hcArtCursor CURSOR LOCAL FAST_FORWARD FOR select artid, pubid from sysmergearticles where nickname = @artnick order by artid, pubid
  20975.                 
  20976.                 OPEN hcArtCursor
  20977.                 FETCH hcArtCursor INTO @artid, @pubid
  20978.                 WHILE (@@fetch_status <> -1)
  20979.                     BEGIN
  20980.                         select @pubname = name, @snapshot_ready = snapshot_ready from sysmergepublications where pubid = @pubid
  20981.                         -- regenerate procs, triggers, and views only for articles with snapshot ready
  20982.                         if @snapshot_ready>0
  20983.                             begin
  20984.                                 declare @rgcol nvarchar(270)
  20985.                                 declare @indname nvarchar(270)
  20986.                                 declare @quotedname nvarchar(270)
  20987.                                 declare @conflict_table sysname
  20988.                                 declare @conflict_table_id int
  20989.                                 declare @owner sysname
  20990.                                 select @article = name, @conflict_table=conflict_table, @conflict_table_id=object_id(conflict_table)  
  20991.                                     from sysmergearticles where artid = @artid and pubid = @pubid
  20992.  
  20993.                                 --make sure conflict table has already got the indexes needed for performance enhancement
  20994.                                 --if not there we will add it up
  20995.                                  if ( @conflict_table_id is not null) and not exists 
  20996.                                      (select * from sysindexes where id = @conflict_table_id and keys is not null)
  20997.                                  begin
  20998.                                     select @owner=user_name(uid) from sysobjects where id= @conflict_table_id
  20999.                                     select @rgcol = QUOTENAME(name) from syscolumns 
  21000.                                         where id = @objid and ColumnProperty(id, name, 'isrowguidcol') = 1
  21001.                                     select @indname = 'uc_' + @conflict_table
  21002.                                     if len(@indname) > 128
  21003.                                     begin
  21004.                                         select @indname = substring(@indname,1,92) + convert(nvarchar(36), newid())
  21005.                                     end
  21006.                                     set @indname = QUOTENAME(@indname)
  21007.                                     set @quotedname = QUOTENAME(@owner) + '.' + QUOTENAME(@conflict_table)
  21008.                                     exec ('Create unique clustered index ' + @indname + ' on ' + @quotedname +
  21009.                                         ' (' + @rgcol + ', origin_datasource)' )
  21010.                                     if @@error <> 0
  21011.                                         return (1)
  21012.                                 end
  21013.                                 
  21014.                                 -- remake the articles procs
  21015.                                 exec @retcode = dbo.sp_MSsetartprocs @publication = @pubname,   @article = @article, @force_flag = 1
  21016.                                 if @@ERROR <>0 OR @retcode <>0 
  21017.                                     return (1)
  21018.                             END
  21019.                         FETCH hcArtCursor INTO @artid, @pubid
  21020.                     END                         
  21021.                 CLOSE hcArtCursor
  21022.                 DEALLOCATE hcArtCursor
  21023.  
  21024.                 -- we no longer try to delete metadata rows that might have truncated colv1
  21025.                 --  deleting can cause non-convergence problems where they previously didn't
  21026.                 --  exist, so we will try to patch up any truncated colv1 values in the merge agent.
  21027.                 
  21028.                 -- find next article
  21029.                 select @artnick = min(a.nickname) from sysmergearticles a inner join sysmergepublications p on p.pubid = a.pubid where p.snapshot_ready > 0 and a.nickname > @artnick
  21030.             end -- end colv metadata fixup, article proc and trigger re-gen
  21031.  
  21032.             -- Loop over publications and recreate the views, skipping publications where snapshot is not ready
  21033.             select @pubname = min(name) from sysmergepublications where UPPER(publisher)=UPPER(@@SERVERNAME) and publisher_db=db_name() and snapshot_ready > 0
  21034.             while @pubname is not null
  21035.             begin
  21036.                 -- remake the publication views
  21037.                 exec dbo.sp_MSpublicationview @pubname, 1
  21038.                 select @pubname = min(name) from sysmergepublications where name > @pubname and UPPER(publisher)=UPPER(@@SERVERNAME) and publisher_db=db_name() and snapshot_ready > 0
  21039.  
  21040.             end
  21041.         end -- end @skip_procgen
  21042.  
  21043.         -- check if the distributor is on the same server as the publisher
  21044.         -- if so fix up the PAL user role.
  21045.         SELECT @distributor = datasource FROM master..sysservers WHERE srvstatus & 8 <> 0
  21046.         IF @@error = 0 and @distributor IS not NULL
  21047.         BEGIN
  21048.             SELECT @distributor = RTRIM(@distributor)
  21049.  
  21050.             -- if the distributor is on the same server. Hence we can fix the pal role
  21051.             -- right now instead of waiting for a snapshot to do it.
  21052.             IF LOWER(@@SERVERNAME) = LOWER(@distributor)
  21053.             BEGIN
  21054.                 declare @role sysname
  21055.                 declare @pubidother uniqueidentifier
  21056.                 -- we need to fix the pal role for all publications in the current database
  21057.                 declare pubs_cursor cursor LOCAL FAST_FORWARD
  21058.                 for select pubid from dbo.sysmergepublications 
  21059.                 where UPPER(publisher) collate database_default = UPPER(@@servername) collate database_default 
  21060.                     and publisher_db = db_name()
  21061.                 open pubs_cursor
  21062.                 fetch pubs_cursor into @pubidother
  21063.                 while (@@fetch_status <> -1)
  21064.                 begin
  21065.                     exec @retcode = sp_MSrepl_FixPALRole @pubidother, @role output
  21066.                     if (@role is NULL or @retcode <> 0 or @@error <> 0)
  21067.                     begin
  21068.                         return 1
  21069.                     end
  21070.                     fetch pubs_cursor into @pubidother
  21071.                 end
  21072.                 close pubs_cursor
  21073.                 deallocate pubs_cursor
  21074.             END
  21075.             else
  21076.             begin
  21077.                 -- force invalidate snapshot for all the publications.
  21078.                 -- this is needed for sp3 upgrade since we have introduced role based
  21079.                 -- security in shiloh sp3. the role will be created and setup when
  21080.                 -- the snapshot agent calls sp_MSenumpubreferences
  21081.                 raiserror(20605, 10, -1)
  21082.                 update dbo.sysmergepublications set snapshot_ready=2 where UPPER(publisher) collate database_default = UPPER(@@servername) collate database_default and publisher_db = db_name()
  21083.             end
  21084.         END
  21085.         else
  21086.         begin
  21087.             -- force invalidate snapshot for all the publications.
  21088.             -- this is needed for sp3 upgrade since we have introduced role based
  21089.             -- security in shiloh sp3. the role will be created and setup when
  21090.             -- the snapshot agent calls sp_MSenumpubreferences
  21091.             update dbo.sysmergepublications set snapshot_ready=2 where UPPER(publisher) collate database_default = UPPER(@@servername) collate database_default and publisher_db = db_name()
  21092.         end
  21093.         
  21094.         -- revoke select access to public on table which were previously granted to public
  21095.         revoke select on MSmerge_errorlineage from public
  21096.         revoke select on MSrepl_identity_range from public
  21097.         revoke select on sysmergearticles from public
  21098.         grant select(nickname,gen_cur,maxversion_at_cleanup) on sysmergearticles to public
  21099.         revoke select on sysmergesubscriptions from public
  21100.         revoke select on MSmerge_replinfo from public
  21101.         revoke select on MSmerge_tombstone from public
  21102.         revoke select on MSmerge_contents from public
  21103.         revoke select on MSmerge_genhistory from public
  21104.         revoke select on MSmerge_delete_conflicts from public
  21105.         revoke select on sysmergeschemachange from public
  21106.         revoke select on sysmergesubsetfilters from public
  21107.     end -- end sysmergearticles modifications
  21108.  
  21109.     SELECT @table_name = N'MSmerge_tombstone'
  21110.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSmerge_tombstone' )
  21111.     BEGIN
  21112.         IF EXISTS (SELECT * FROM sysindexes WHERE name = 'unc3MSmerge_tombstone' AND id = OBJECT_ID('MSmerge_tombstone'))
  21113.             drop index MSmerge_tombstone.unc3MSmerge_tombstone
  21114.         
  21115.     END
  21116.  
  21117.     SELECT @table_name = N'MSmerge_contents'
  21118.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSmerge_contents' )
  21119.     BEGIN
  21120.         IF EXISTS (SELECT * FROM sysindexes WHERE name = 'nc2MSmerge_contents' AND id = OBJECT_ID('MSmerge_contents'))
  21121.             drop index MSmerge_contents.nc2MSmerge_contents
  21122.  
  21123.         IF EXISTS (SELECT * FROM sysindexes WHERE name = 'nc3MSmerge_contents' AND id = OBJECT_ID('MSmerge_contents'))
  21124.             drop index MSmerge_contents.nc3MSmerge_contents
  21125.  
  21126.         IF EXISTS (SELECT * FROM sysindexes WHERE name = 'nc4MSmerge_contents' AND id = OBJECT_ID('MSmerge_contents'))
  21127.             drop index MSmerge_contents.nc4MSmerge_contents
  21128.  
  21129.         IF EXISTS (SELECT * FROM sysindexes WHERE name = 'unc3SycContents' AND id = OBJECT_ID('MSmerge_contents'))
  21130.             drop index MSmerge_contents.unc3SycContents
  21131.         
  21132.         create index nc2MSmerge_contents on MSmerge_contents(generation)
  21133.         if @@ERROR <> 0 return 1
  21134.  
  21135.         create index nc3MSmerge_contents on MSmerge_contents(partchangegen)
  21136.         if @@ERROR <> 0 return 1
  21137.  
  21138.         create index nc4MSmerge_contents on MSmerge_contents(rowguid)
  21139.         if @@ERROR <> 0 return 1
  21140.     END
  21141.  
  21142.     if (exists (select * from sysobjects where name = 'sysmergearticles'))
  21143.     begin
  21144.         -- before image tables
  21145.         declare @binames table (biname sysname)
  21146.         insert into @binames select name from sysobjects 
  21147.                                 where xtype='U' 
  21148.                                 and name like 'MS_bi%'
  21149.                                 and id in (select before_image_objid from sysmergearticles)
  21150.         declare @biname nvarchar(255)
  21151.         set @biname= (select top 1 biname from @binames)
  21152.         while @biname is not null
  21153.         begin
  21154.             set @cmd= 'drop index ' + quotename(@biname) + '.' + quotename(@biname + '_gen')
  21155.             exec dbo.sp_executesql @cmd
  21156.             set @cmd= 'create clustered index ' + quotename(@biname + '_gen') + ' on ' + quotename(@biname) + '(generation)'
  21157.             exec dbo.sp_executesql @cmd
  21158.             delete from @binames where biname=@biname
  21159.             set @biname= (select top 1 biname from @binames)
  21160.         end
  21161.     end
  21162.  
  21163.     -- remove orphaned rows in MSmerge_contents
  21164.     if (
  21165.             exists (select * from sysobjects where name = 'sysmergearticles') and
  21166.             exists (select * from sysobjects where name = 'sysmergepublications') and
  21167.             exists (select * from sysobjects where name = 'MSmerge_genhistory') and
  21168.             exists (select * from sysobjects where name = 'MSmerge_contents') and
  21169.             exists (select * from sysobjects where name = 'MSmerge_tombstone')
  21170.         )
  21171.     begin
  21172.         exec @retcode= sp_MSpurgecontentsorphans
  21173.         if @retcode<>0 or @@error<>0 return 1
  21174.     end
  21175. end
  21176. GO
  21177. exec sp_MS_marksystemobject 'sp_vupgrade_mergetables'
  21178. go
  21179.  
  21180. raiserror('Creating procedure sp_vupgrade_subpass', 0,1)
  21181. GO
  21182. create procedure sp_vupgrade_subpass
  21183. as
  21184. begin
  21185.     /* 
  21186.      * Upgrade replication ftp_password and distributor_passwords
  21187.      * in subscriber database.
  21188.      *
  21189.      * Setup version upgrade procedure call order:
  21190.      *    sp_vupgrade_replication -> sp_vupgrade_subscription_databases -> sp_vupgrade_subpass
  21191.     */
  21192.     begin transaction
  21193.  
  21194.     /*
  21195.      * MSsubscription_properties
  21196.     */
  21197.     if exists (select name from sysobjects where name='MSsubscription_properties')
  21198.     begin
  21199.         if not exists (select * from syscolumns where id = Object_Id('MSsubscription_properties') and name = 'ftp_password' and length = '1048')
  21200.         begin
  21201.             declare @dbname sysname
  21202.             declare @cmptlevel tinyint
  21203.             set @dbname = db_name()
  21204.             select @cmptlevel = cmptlevel from master..sysdatabases where name = @dbname collate database_default
  21205.             if @cmptlevel < 70
  21206.             begin
  21207.                                 raiserror (15048, -1, -1, 70, 70, 70, 80)
  21208.             end
  21209.             else
  21210.             begin
  21211.                     /*
  21212.                  * alter ftp_password column from sysname to nvarchar(524)
  21213.                 */
  21214.                 exec( 'alter table MSsubscription_properties alter column ftp_password nvarchar(524)' )
  21215.                 exec( 'alter table MSsubscription_properties alter column distributor_password nvarchar(524)' )
  21216.                 exec( 'alter table MSsubscription_properties alter column publisher_password nvarchar(524)' )
  21217.                 exec( 'alter table MSsubscription_properties alter column dts_package_password nvarchar(524)' )
  21218.             end
  21219.  
  21220.             /*
  21221.              * convert all the ftp_passwords to new encryption
  21222.              */
  21223.             declare @ftp_password nvarchar(524)
  21224.             declare @distributor_password nvarchar(524)
  21225.             declare @publisher_password nvarchar(524)
  21226.             declare @dts_package_password nvarchar(524)
  21227.             declare @retcode int
  21228.  
  21229.             declare cur_MSsubscription_properties CURSOR LOCAL FORWARD_ONLY for 
  21230.             select ftp_password, distributor_password, publisher_password, dts_package_password
  21231.             from MSsubscription_properties
  21232.             for update of ftp_password, distributor_password, publisher_password, dts_package_password
  21233.         
  21234.             open cur_MSsubscription_properties
  21235.             fetch next from cur_MSsubscription_properties into @ftp_password, @distributor_password, @publisher_password, @dts_package_password
  21236.             while ( @@fetch_status <> -1 )
  21237.             begin
  21238.                 EXEC @retcode = master.dbo.xp_repl_convert_encrypt @ftp_password OUTPUT
  21239.                 IF @@error <> 0 OR @retcode <> 0
  21240.                 begin
  21241.                     rollback transaction
  21242.                     return 1
  21243.                 end
  21244.                       
  21245.                 EXEC @retcode = master.dbo.xp_repl_convert_encrypt @distributor_password OUTPUT
  21246.                 IF @@error <> 0 OR @retcode <> 0
  21247.                 begin
  21248.                     rollback transaction
  21249.                     return 1
  21250.                 end
  21251.     
  21252.                 EXEC @retcode = master.dbo.xp_repl_convert_encrypt @publisher_password OUTPUT
  21253.                 IF @@error <> 0 OR @retcode <> 0
  21254.                 begin
  21255.                     rollback transaction
  21256.                     return 1
  21257.                 end
  21258.  
  21259.                 EXEC @retcode = master.dbo.xp_repl_convert_encrypt @dts_package_password OUTPUT
  21260.                 IF @@error <> 0 OR @retcode <> 0
  21261.                 begin
  21262.                     rollback transaction
  21263.                     return 1
  21264.                 end
  21265.            
  21266.                 update MSsubscription_properties
  21267.                 set ftp_password=@ftp_password, distributor_password=@distributor_password, publisher_password=@publisher_password, dts_package_password=@dts_package_password
  21268.                 where current of cur_MSsubscription_properties
  21269.         
  21270.                     fetch next from cur_MSsubscription_properties into @ftp_password, @distributor_password, @publisher_password, @dts_package_password
  21271.             end
  21272.         end
  21273.     end
  21274.     commit transaction
  21275. end
  21276. GO
  21277. exec sp_MS_marksystemobject 'sp_vupgrade_subpass'
  21278. go
  21279.  
  21280. raiserror('Creating procedure sp_vupgrade_MSsubscription_properties', 0,1)
  21281. GO
  21282. create procedure sp_vupgrade_MSsubscription_properties
  21283. as
  21284. begin
  21285. /* 
  21286.  * Process schema and metadata changes common to transactional and merge MSsubscription_properties.
  21287.  *
  21288.  * Setup version upgrade procedure call order:
  21289.  *    sp_vupgrade_replication -> sp_vupgrade_subscription_databases -> sp_vupgrade_MSsubscription_properties
  21290. */
  21291.     set nocount on 
  21292.  
  21293.     declare @cmd nvarchar(1000)
  21294.     declare @table_name sysname
  21295.  
  21296.     -- raiserror('sp_vupgrade_MSsubscription_properties', 0,1)
  21297.  
  21298.     if exists( select * from sysobjects where name = 'MSsubscription_properties'
  21299.         and type = 'U')
  21300.     begin
  21301.         -- Add FTP properties to MSsubscription_properties.  
  21302.         if not exists (select * from syscolumns where name = 'ftp_address' and
  21303.             id = OBJECT_ID('MSsubscription_properties'))
  21304.         begin
  21305.             alter table MSsubscription_properties ADD ftp_address sysname NULL
  21306.             if @@ERROR <> 0
  21307.                 return 1
  21308.         end
  21309.  
  21310.         if not exists (select * from syscolumns where name = 'ftp_port' and
  21311.             id = OBJECT_ID('MSsubscription_properties'))
  21312.         begin
  21313.             alter table MSsubscription_properties ADD ftp_port int NULL
  21314.             if @@ERROR <> 0
  21315.                 return 1
  21316.         end
  21317.  
  21318.         if not exists (select * from syscolumns where name = 'ftp_login' and
  21319.             id = OBJECT_ID('MSsubscription_properties'))
  21320.         begin
  21321.             alter table MSsubscription_properties ADD ftp_login sysname NULL
  21322.             if @@ERROR <> 0
  21323.                 return 1
  21324.         end
  21325.  
  21326.         if not exists (select * from syscolumns where name = 'ftp_password' and
  21327.             id = OBJECT_ID('MSsubscription_properties'))
  21328.         begin
  21329.             alter table MSsubscription_properties ADD ftp_password sysname NULL
  21330.             if @@ERROR <> 0
  21331.                 return 1
  21332.         end
  21333.  
  21334.         -- Portable snapshot (Shiloh)
  21335.         if not exists (select * from syscolumns where name = 'alt_snapshot_folder' and
  21336.             id = OBJECT_ID('MSsubscription_properties'))
  21337.         begin
  21338.             alter table MSsubscription_properties ADD alt_snapshot_folder nvarchar(255) NULL
  21339.             if @@ERROR <> 0
  21340.                 return 1
  21341.         end
  21342.  
  21343.         if not exists (select * from syscolumns where name = 'working_directory' and
  21344.             id = OBJECT_ID('MSsubscription_properties'))
  21345.         begin
  21346.  
  21347.             alter table MSsubscription_properties ADD working_directory nvarchar(255) NULL
  21348.             if @@ERROR <> 0
  21349.                 return 1
  21350.         end
  21351.  
  21352.         -- Subscriber need only set this bit and have valid login info to publisher (Shiloh)
  21353.         if not exists (select * from syscolumns where name = 'use_ftp' and
  21354.             id = OBJECT_ID('MSsubscription_properties'))
  21355.         begin
  21356.  
  21357.             alter table MSsubscription_properties ADD use_ftp bit default 0 NOT NULL
  21358.             if @@ERROR <> 0
  21359.                 return 1
  21360.         end
  21361.  
  21362.         -- Since ftp login information is not required to be persisted at the 
  21363.         -- database anymore and the use_ftp column is now the sole indicator 
  21364.         -- of whether ftp is going to be used for a particular subscription,
  21365.         -- set the use_ftp column to 1 for subscriptions that used to have
  21366.         -- a non-null ftp address
  21367.         if exists (select * from syscolumns where id = object_id('MSsubscription_properties') and
  21368.             name = 'ftp_address')
  21369.         begin
  21370.             -- must exec in separate process; deferred syntax will fail if update references non-existent column
  21371.             select @cmd = 'update dbo.MSsubscription_properties set use_ftp = 1 where ftp_address is not null and ftp_address <> N'''''
  21372.             exec (@cmd)
  21373.         end 
  21374.  
  21375.         -- Transformable subscriptions (Shiloh)
  21376.         if not exists (select * from syscolumns where name = 'dts_package_name' and
  21377.             id = OBJECT_ID('MSsubscription_properties'))
  21378.         begin
  21379.             alter table MSsubscription_properties ADD dts_package_name sysname NULL
  21380.             if @@ERROR <> 0
  21381.                 return 1
  21382.         end
  21383.  
  21384.         if not exists (select * from syscolumns where name = 'dts_package_password' and
  21385.             id = OBJECT_ID('MSsubscription_properties'))
  21386.         begin
  21387.             alter table MSsubscription_properties ADD dts_package_password nvarchar(524) NULL
  21388.             if @@ERROR <> 0
  21389.                 return 1
  21390.         end
  21391.  
  21392.         if not exists (select * from syscolumns where name = 'dts_package_location' and
  21393.             id = OBJECT_ID('MSsubscription_properties'))
  21394.         begin
  21395.             alter table MSsubscription_properties ADD dts_package_location int default 1 NOT NULL
  21396.             if @@ERROR <> 0
  21397.                 return 1
  21398.         end
  21399.  
  21400.         -- Windows Synchronization Manager support (Shiloh)
  21401.         if not exists (select * from syscolumns where name = 'enabled_for_syncmgr' and
  21402.             id = OBJECT_ID('MSsubscription_properties'))
  21403.         begin
  21404.             alter table MSsubscription_properties ADD enabled_for_syncmgr bit default 0 NOT NULL
  21405.             if @@ERROR <> 0
  21406.                 return 1
  21407.         end
  21408.  
  21409.         -- Remote (DCOM) agents support (Shiloh)
  21410.         if not exists (select * from syscolumns where id = object_id('MSsubscription_properties') and
  21411.             name = 'offload_agent')
  21412.         begin
  21413.             alter table MSsubscription_properties ADD offload_agent bit default 0 NOT NULL
  21414.             if @@ERROR <> 0
  21415.                 return 1
  21416.         end
  21417.  
  21418.         if not exists (select * from syscolumns where id = object_id('MSsubscription_properties') and
  21419.             name = 'offload_server')
  21420.         begin
  21421.             alter table MSsubscription_properties ADD offload_server sysname default NULL
  21422.             if @@ERROR <> 0
  21423.                 return 1
  21424.         end        
  21425.  
  21426.         -- Dynamic snapshot location (Shiloh)
  21427.         if not exists (select * from syscolumns where id = object_id('MSsubscription_properties') and
  21428.             name = 'dynamic_snapshot_location')
  21429.         begin
  21430.             alter table MSsubscription_properties ADD dynamic_snapshot_location sysname default NULL
  21431.             
  21432.             if @@ERROR <> 0
  21433.                 return 1
  21434.         end
  21435.  
  21436.         --    MSsubscription_properties indexes (SQL7.0 SP1)
  21437.         select @table_name = N'MSsubscription_properties'
  21438.         if exists( select * from sysobjects where name = 'MSsubscription_properties' ) 
  21439.         begin
  21440.             if exists( select publication, publisher_db, publisher
  21441.                 from MSsubscription_properties
  21442.                 group by publication, publisher_db, publisher
  21443.                 having count(*) > 1 )
  21444.                 raiserror(21203, 10, 2, @table_name)
  21445.             else
  21446.                 if not exists( select * from sysindexes where name = 'uc1MSsubscription_properties' and
  21447.                     id = OBJECT_ID('MSsubscription_properties') )
  21448.                     create unique clustered index uc1MSsubscription_properties on
  21449.                     MSsubscription_properties(publication, publisher_db, publisher)
  21450.         end
  21451.     end
  21452.  
  21453. end
  21454. go
  21455. exec sp_MS_marksystemobject 'sp_vupgrade_MSsubscription_properties'
  21456. go
  21457.  
  21458. raiserror('Creating procedure sp_vupgrade_replication', 0,1)
  21459. GO
  21460.  
  21461. create procedure sp_vupgrade_replication ( @login sysname = N'sa', @password sysname = N'', @ver_old int = 517, @force_remove tinyint = 0, @security_mode bit = 0 )
  21462. as
  21463. begin
  21464. /* 
  21465.  * Dispatcher proc for handling schema and metadata changes during setup initiated version upgrade 
  21466.  * for replication components. Any schema changes to replication system tables may require modifications 
  21467.  * here to maintain upgrade path. All modifications called in these procs are within "if exists" checks
  21468.  * making them repeatable for debugging and to support incremental upgrades (e.g. Beta 1 to Beta 2 to RTM)
  21469.  * 
  21470.  * If server is a distributor, run new instdist.sql against all distribution dbs.
  21471.  *
  21472.  * This proc gets called by setup at the end of an install over an existing version.
  21473. */
  21474.  
  21475.     set nocount on 
  21476.  
  21477.     declare @dbname sysname
  21478.     declare @has_dbaccess bit
  21479.     declare @install_path nvarchar(255)
  21480.     declare @osql_path nvarchar(260)
  21481.     declare @osql_cmd nvarchar(512)
  21482.     declare @osql_for_nt int
  21483.     declare @retcode int
  21484.     declare @platform_nt binary
  21485.     declare @db_distbit int
  21486.     declare @ver_min             int
  21487.     declare @ver_retention    int 
  21488.  
  21489.     select @db_distbit = 16
  21490.     select @platform_nt = 0x1
  21491.     select @ver_retention = 576 --build # on 9/17
  21492.  
  21493.     -- raiserror('sp_vupgrade_replication', 0,1) with nowait
  21494.  
  21495.     /*
  21496.      * obsolete check; ver check was to prevent repl upgrade from
  21497.      * versions prior to SQL7.0 Beta 3; check is removed by setting @ver_min = -1
  21498.     */
  21499.     select @ver_min= -1 -- change if later wish to support a minimum upgrade version
  21500.     if ( @ver_old < @ver_min ) or ( @force_remove = 1 )
  21501.         exec dbo.sp_removesrvreplication
  21502.     else
  21503.     begin
  21504.  
  21505.         /* 
  21506.          * always need to run instdist.sql to update distribution databases on a distributor
  21507.          * setup must restart in non-single user mode so we can shell out to run instdist.sql scripts
  21508.         */
  21509.         if exists( select * from master..sysdatabases where category & @db_distbit = @db_distbit )
  21510.         begin
  21511.  
  21512.             /* 
  21513.             ** Get installation path -- osql client (TOOLS) path
  21514.             */
  21515.             EXECUTE @retcode = master.dbo.sp_MSgettools_path @osql_path OUTPUT
  21516.             IF ( @@ERROR <> 0 ) OR ( @retcode <> 0 ) or ( @osql_path is NULL ) or ( @osql_path = '' )
  21517.             BEGIN
  21518.                 RETURN (1)
  21519.             END
  21520.  
  21521.             /* 
  21522.             ** Get installation path -- instance specific (INSTALL) directory
  21523.             */
  21524.             exec @retcode = master.dbo.sp_MSget_setup_paths
  21525.                 @sql_path = @install_path output
  21526.             IF @@ERROR<> 0 OR @retcode <> 0 or @install_path is NULL or @install_path=N''
  21527.             BEGIN
  21528.                 RETURN (1)
  21529.             END
  21530.  
  21531.             -- Set the flag for platform
  21532.             if (( platform() & @platform_nt = @platform_nt ))
  21533.                 select @osql_for_nt = 1
  21534.             else
  21535.                 select @osql_for_nt = 0
  21536.  
  21537.             declare cur_distdb CURSOR LOCAL FAST_FORWARD for 
  21538.                 select name, has_dbaccess(name) from master..sysdatabases 
  21539.                     where category & @db_distbit = @db_distbit
  21540.                 for read only
  21541.             
  21542.             open cur_distdb
  21543.             fetch cur_distdb into @dbname, @has_dbaccess
  21544.             while ( @@fetch_status <> -1 )
  21545.             begin
  21546.  
  21547.                 -- if distribution database is available upgrade it; if offline error out
  21548.                 if ( @has_dbaccess = 1 )
  21549.                 begin
  21550.                     raiserror( 21374, 0, 1, @dbname) with nowait
  21551.  
  21552.                     /*
  21553.                      * Format osql cmd line appropriate for security mode and OS to run instdist.sql against
  21554.                      * each distribution database. Instdist.sql will recompile procs and will also do some
  21555.                      * schema and metadata upgrade of changed replication tables. Query timeout increased to
  21556.                      * make enough time for alter tables in instdist.sql run for upgrade to complete.
  21557.                     */
  21558.                     if ( @osql_for_nt = 1 )
  21559.                         select @osql_cmd = N'" "'
  21560.                     else
  21561.                         select @osql_cmd = N' "'
  21562.                     
  21563.                     -- Cannot specify -S w/ -E for local execution, SID does not map (nofix)
  21564.                     if ( @security_mode = 1 and @osql_for_nt = 1 )
  21565.                     begin
  21566.                         select @osql_cmd = @osql_cmd + fn_escapecmdshellsymbolsremovequotes(@osql_path) collate database_default + '\binn\osql" -E '
  21567.                         if serverproperty('instancename') is not null
  21568.                             select @osql_cmd = @osql_cmd + ' -S"' + fn_escapecmdshellsymbols(@@SERVERNAME) collate database_default + '" '
  21569.                     end
  21570.                     else
  21571.                         select @osql_cmd = @osql_cmd + fn_escapecmdshellsymbolsremovequotes(@osql_path) collate database_default + '\binn\osql" -U' + fn_escapecmdshellsymbols(isnull(@login, N'sa')) collate database_default + ' -P' + fn_escapecmdshellsymbols(isnull(@password, N'')) collate database_default + ' -S"' + fn_escapecmdshellsymbols(@@SERVERNAME) collate database_default + '" '
  21572.  
  21573.                     select @osql_cmd = @osql_cmd + ' -l30 -t120 '
  21574.                     select @osql_cmd = @osql_cmd + ' -b ' + ' -d' + fn_escapecmdshellsymbols(@dbname) collate database_default
  21575.                     select @osql_cmd = @osql_cmd +    ' -i' + '"' + fn_escapecmdshellsymbolsremovequotes(@install_path) collate database_default + '\install\instdist.sql"' + 
  21576.                                                     ' -o' + '"' + fn_escapecmdshellsymbolsremovequotes(@install_path) collate database_default + '\install\instdist.out"'            
  21577.  
  21578.  
  21579.                     if (@osql_for_nt = 1)
  21580.                         select @osql_cmd = @osql_cmd + ' "'
  21581.  
  21582.                      exec @retcode = master..xp_cmdshell @osql_cmd
  21583.                     if @retcode <> 0 or @@error <> 0
  21584.                     begin
  21585.                         raiserror (14113, 16, -1, @osql_cmd, 'instdist.out')
  21586.                     end
  21587.  
  21588.                     /*
  21589.                      * Process schema and metadata changes for each distribution database
  21590.                     */
  21591.  
  21592.                     select @dbname = quotename(@dbname)
  21593.                     exec ('use '+ @dbname + ' exec dbo.sp_vupgrade_distdb')
  21594.                     if @@error <> 0
  21595.                         return(1)
  21596.                 end
  21597.                 else
  21598.                 begin
  21599.                     /* Report informational message stating distribution
  21600.                     ** database is not accessible.
  21601.                     */
  21602.                     raiserror( 21378, 10, 1, @dbname) with nowait
  21603.                 end
  21604.                 
  21605.                 fetch next from cur_distdb into @dbname, @has_dbaccess
  21606.             end
  21607.             close cur_distdb
  21608.             deallocate cur_distdb
  21609.         end
  21610.  
  21611.         -- vupgrade_publisher runs at 
  21612.         exec @retcode = dbo.sp_vupgrade_publisher 
  21613.             @ver_old = @ver_old, 
  21614.             @ver_retention = @ver_retention
  21615.         if @retcode<>0 or @@error<>0
  21616.             return (1)
  21617.     
  21618.         -- Update subscription database schema
  21619.         exec @retcode = dbo.sp_vupgrade_subscription_databases
  21620.         if @retcode <> 0 or @@error <> 0
  21621.             return (1)
  21622.  
  21623.  
  21624.     end
  21625.  
  21626.     return (0)
  21627.  
  21628. end
  21629. go
  21630.  
  21631. exec dbo.sp_MS_marksystemobject sp_vupgrade_replication
  21632. go
  21633.  
  21634.  
  21635. raiserror('Creating procedure sp_vupgrade_distdb', 0,1)
  21636. go
  21637. create procedure sp_vupgrade_distdb 
  21638. as
  21639. begin
  21640. /* 
  21641.  * Process schema and metadata changes specific to a distribution database. Some schema modifications
  21642.  * may have already been made by the apply of instdist.sql against the distribution database. Both steps
  21643.  * are needed for a complete distribution database upgrade.
  21644.  *
  21645.  * Setup version upgrade procedure call order:
  21646.  *    sp_vupgrade_replication -> sp_vupgrade_distdb
  21647. */
  21648.  
  21649.     set nocount on
  21650.  
  21651.     declare @table_name sysname
  21652.     declare @retcode integer
  21653.  
  21654.     -- raiserror('sp_vupgrade_publisher', 0,1) with nowait
  21655.     /*
  21656.      * MSdistribution_agents
  21657.     */
  21658.     if exists (select name from sysobjects where name='MSdistribution_agents')
  21659.     begin
  21660.         if not exists (select * from syscolumns where id = object_id('MSdistribution_agents') and name = 'queue_server')
  21661.         begin
  21662.             alter table MSdistribution_agents add queue_server sysname null
  21663.             EXEC dbo.sp_MSupdate_mqserver_distdb
  21664.         end
  21665.     end
  21666.     /* mark helper tables in msdb as system object */
  21667.     IF EXISTS (SELECT * FROM msdb..sysobjects WHERE name = 'MSdistpublishers'
  21668.         and xtype = 'U')
  21669.     begin
  21670.         exec msdb.dbo.sp_MS_marksystemobject MSdistpublishers
  21671.     end
  21672.  
  21673.     /* Create MSdistributiondbs table */
  21674.     IF EXISTS (SELECT * FROM msdb..sysobjects WHERE name = 'MSdistributiondbs'
  21675.         and xtype = 'U')
  21676.     begin
  21677.         exec msdb.dbo.sp_MS_marksystemobject MSdistributiondbs
  21678.     end
  21679.  
  21680.     /* create MSdistributor table */
  21681.     IF EXISTS (SELECT * FROM msdb..sysobjects WHERE name = 'MSdistributor'
  21682.         and xtype = 'U')
  21683.     begin
  21684.         exec msdb.dbo.sp_MS_marksystemobject MSdistributor
  21685.     end
  21686.  
  21687.     /* create sysreplicationalerts table */
  21688.     IF EXISTS (SELECT * FROM msdb..sysobjects WHERE name = 'sysreplicationalerts'
  21689.         and xtype = 'U')
  21690.     begin
  21691.         exec msdb.dbo.sp_MS_marksystemobject sysreplicationalerts
  21692.     end
  21693.     
  21694.     /* create MSagent_profiles table */
  21695.     IF EXISTS (SELECT * FROM msdb..sysobjects WHERE name = 'MSagent_profiles'
  21696.         and xtype = 'U')
  21697.     begin
  21698.         exec msdb.dbo.sp_MS_marksystemobject MSagent_profiles
  21699.     end
  21700.  
  21701.     /* create MSagent_parameters table */
  21702.     IF EXISTS (SELECT * FROM msdb..sysobjects WHERE name = 'MSagent_parameters' 
  21703.         and xtype = 'U')
  21704.     begin
  21705.         exec msdb.dbo.sp_MS_marksystemobject MSagent_parameters
  21706.     end
  21707.  
  21708.     /* create MSdatatype_mappings table */
  21709.     IF EXISTS (SELECT * FROM msdb..sysobjects WHERE name = 'MSdatatype_mappings' 
  21710.         and xtype = 'U')
  21711.     begin
  21712.         exec msdb.dbo.sp_MS_marksystemobject MSdatatype_mappings
  21713.     end
  21714.  
  21715.  
  21716.  
  21717.     
  21718.  
  21719. end
  21720. go
  21721.  
  21722. exec dbo.sp_MS_marksystemobject sp_vupgrade_distdb
  21723. go
  21724.  
  21725.  
  21726. raiserror('Creating procedure sp_vupgrade_publisher', 0,1)
  21727. go
  21728. create procedure sp_vupgrade_publisher @ver_old int, @ver_retention int
  21729. as
  21730. begin
  21731. /* 
  21732.  * Process schema and metadata changes specific to a publisher and dispatch calls to sp_vupgrade_publisherdb
  21733.  * for any databases marked with the publishing bits.
  21734.  *
  21735.  * Setup version upgrade procedure call order:
  21736.  *    sp_vupgrade_replication -> sp_vupgrade_publisher
  21737. */
  21738.  
  21739.     set nocount on
  21740.  
  21741.     declare @proc_name            nvarchar(350)
  21742.     declare @publication        sysname
  21743.     declare @upgraded            bit 
  21744.     declare @retcode             int
  21745.     declare @publisher_db        nvarchar(270)
  21746.     declare @agentname            sysname
  21747.     declare @has_dbaccess        bit
  21748.  
  21749.     -- raiserror('sp_vupgrade_publisher', 0,1)
  21750.  
  21751.     /*
  21752.      * Expired subscription cleanup agent name needs set to localized string (message 20569) and 
  21753.      * jobstep set to correct procedure name based on name change between SQL7.0 and SQL7.5
  21754.     */
  21755.     set @agentname = formatmessage(20569)  
  21756.     
  21757.     update msdb.dbo.sysjobs
  21758.         set name = @agentname
  21759.         from msdb.dbo.sysjobs, msdb.dbo.sysjobsteps as s
  21760.         where msdb.dbo.sysjobs.job_id = s.job_id
  21761.         and 
  21762.         ( upper(s.command) = upper(N'EXEC sp_MScleanup_subscription') 
  21763.         or upper(s.command) = upper(N'EXEC dbo.sp_MScleanup_subscription') )
  21764.  
  21765.     update msdb.dbo.sysjobsteps 
  21766.         set  command = N'EXEC dbo.sp_expired_subscription_cleanup' 
  21767.         where upper(command) = upper(N'EXEC sp_MScleanup_subscription')
  21768.         or upper(command) = upper(N'EXEC dbo.sp_MScleanup_subscription')
  21769.             
  21770.     /*
  21771.      * Process schema and metadata changes for each publishing database on the publisher.
  21772.      * 
  21773.      * Transactional replication system tables at the publisher are updated by sp_vupgrade_publisherdb.
  21774.      * Most merge system tables exist in both the publishing and subscribing databases; merge schema 
  21775.      * and metadata changes are processed by a separate pass over all databases in sp_vupgrade_mergetables.
  21776.     */
  21777.     declare DC cursor local FAST_FORWARD for select distinct N'[' + replace(name, N']', N']]') + N']', has_dbaccess(name) from master..sysdatabases 
  21778.     --    where ((category & 4) = 4) or ((category & 1) = 1)
  21779.             WHERE name <> N'master' collate database_default
  21780.             AND name <> N'tempdb' collate database_default
  21781.             AND name <> N'msdb' collate database_default
  21782.         for read only
  21783.     open DC
  21784.     fetch DC into @publisher_db, @has_dbaccess
  21785.     while (@@fetch_status <> -1)
  21786.     begin
  21787.         -- upgrade repl tables in publishing dbs if needed
  21788.         -- skip any database in an offline state and write warning to upgrade log
  21789.         if ( @has_dbaccess = 1 )
  21790.         begin
  21791.             raiserror( 21375, 10, 1, @publisher_db) with nowait
  21792.  
  21793.             select @proc_name = @publisher_db + '.dbo.sp_vupgrade_publisherdb'
  21794.             exec @retcode = @proc_name 
  21795.                 @ver_old = @ver_old,
  21796.                 @ver_retention = @ver_retention
  21797.             if @retcode<>0 or @@ERROR<>0
  21798.             begin
  21799.                 close DC
  21800.                 deallocate DC
  21801.                 return (1)
  21802.             end
  21803.         end
  21804.         else
  21805.         begin 
  21806.             -- report informational message stating database is not accessible.
  21807.             raiserror( 21376, 10, 1, @publisher_db) with nowait
  21808.         end
  21809.  
  21810.         fetch DC into @publisher_db, @has_dbaccess
  21811.  
  21812.     end
  21813.     close DC
  21814.     deallocate DC
  21815.         
  21816.     /*
  21817.      * We need to mark sp_MScleanupmergepublisher as a startup procedure
  21818.      * if there are any databases enabled for merge replication.
  21819.      */
  21820.     if exists (select * from sysdatabases where (category & 4) <> 0)
  21821.     begin
  21822.         exec dbo.sp_procoption 'sp_MScleanupmergepublisher', 'startup', 'true'
  21823.     end
  21824.  
  21825. end
  21826. go
  21827.  
  21828. exec dbo.sp_MS_marksystemobject sp_vupgrade_publisher
  21829. go
  21830.  
  21831.  
  21832. raiserror('Creating procedure sp_vupgrade_syscol_status', 0,1)
  21833. go
  21834. create procedure sp_vupgrade_syscol_status
  21835. as
  21836. begin
  21837. /* 
  21838.  * Transactional published tables should have their column bits set to indicate they are published.
  21839.  *
  21840.  * Setup version upgrade procedure call order:
  21841.  *    sp_vupgrade_replication -> sp_vupgrade_publisher -> sp_vupgrade_publisherdb -> sp_vupgrade_syscol_status
  21842. */
  21843.  
  21844.     set nocount on 
  21845.  
  21846.     declare @artid int
  21847.     declare @src_objid int
  21848.     declare @columns binary(32)
  21849.     declare @this_col int
  21850.     declare @isset int
  21851.  
  21852.     -- raiserror('sp_vupgrade_syscol_status', 0,1) with nowait
  21853.  
  21854.     -- cursor through table based articles
  21855.     declare hCArt cursor local FAST_FORWARD for 
  21856.         select artid, objid, columns from sysarticles where type & 1 = 1
  21857.     open hCArt
  21858.     fetch hCArt into @artid, @src_objid, @columns
  21859.     while (@@fetch_status <> -1)
  21860.     begin
  21861.         -- cursor through columns on replicated object
  21862.         declare hCColid cursor local FAST_FORWARD for 
  21863.             select colid from syscolumns where id = @src_objid
  21864.         open hCColid
  21865.         fetch hCColid into @this_col
  21866.         while (@@fetch_status <> -1)
  21867.         begin
  21868.            exec @isset = dbo.sp_isarticlecolbitset @this_col, @columns
  21869.            if @isset != 0 
  21870.            begin
  21871.                 exec sp_MSarticlecol @artid, @this_col, 'publish', 'add'
  21872.            end
  21873.            fetch hCColid into @this_col
  21874.         end
  21875.         close hCColid
  21876.         deallocate hCColid
  21877.  
  21878.         fetch hCArt into @artid, @src_objid, @columns
  21879.     end
  21880.  
  21881.     close hCArt
  21882.     deallocate hCArt
  21883. end
  21884. go
  21885. exec dbo.sp_MS_marksystemobject sp_vupgrade_syscol_status
  21886. go
  21887.  
  21888. raiserror('Creating procedure sp_vupgrade_publisherdb', 0,1)
  21889. go
  21890. create procedure sp_vupgrade_publisherdb @ver_old int, @ver_retention int
  21891. as
  21892. begin
  21893. /* 
  21894.  * Process schema and metadata changes specific to a publishing database. Transactional replication 
  21895.  * system tables at the publisher are updated by sp_vupgrade_publisherdb; merge tables are not.
  21896.  * Most merge system tables exist in both the publishing and subscribing databases; merge schema 
  21897.  * and metadata changes are processed by a separate pass over all databases in sp_vupgrade_mergetables.
  21898.  *
  21899.  * Match column order of newly created table when adding columns.
  21900.  *
  21901.  * Setup version upgrade procedure call order:
  21902.  *    sp_vupgrade_replication -> sp_vupgrade_publisher -> sp_vupgrade_publisherdb
  21903. */
  21904.  
  21905.     set nocount on 
  21906.  
  21907.     declare @default_name sysname 
  21908.  
  21909.     -- raiserror('sp_vupgrade_publisherdb', 0,1) with nowait
  21910.  
  21911.     -- syssubscriptions
  21912.     if exists (select name from sysobjects where name='syssubscriptions')
  21913.     begin
  21914.         if not exists (select * from syscolumns where id = object_id('syssubscriptions') and 
  21915.             name = 'queued_reinit')
  21916.         begin
  21917.             alter table syssubscriptions add queued_reinit bit default 0 not null
  21918.         end
  21919.  
  21920.     end -- end of syssubscriptions upgrade
  21921.  
  21922.     -- syspublications
  21923.     if exists (select name from sysobjects where name='syspublications')
  21924.     begin
  21925.  
  21926.         -- default_access column no longer used
  21927.         if exists (select * from syscolumns where id = object_id('syspublications') and
  21928.             name = 'default_access')
  21929.         begin
  21930.             alter table syspublications drop column default_access
  21931.         end 
  21932.  
  21933.         /*
  21934.          * Queued updating subscriptions option; conflict management settings added later in this proc
  21935.         */
  21936.         if not exists (select * from syscolumns where id = object_id('syspublications') and 
  21937.             name = 'allow_queued_tran')
  21938.         begin
  21939.             alter table syspublications add allow_queued_tran bit default 0 not null
  21940.         end
  21941.  
  21942.         /*
  21943.          * Portable snapshot
  21944.         */
  21945.         if not exists (select * from syscolumns where id = object_id('syspublications') and name = 'snapshot_in_defaultfolder')
  21946.         begin
  21947.             alter table syspublications add snapshot_in_defaultfolder bit default 1 not null
  21948.         end
  21949.     
  21950.         if not exists (select * from syscolumns where id = object_id('syspublications') and name = 'alt_snapshot_folder')
  21951.         begin
  21952.             alter table syspublications add alt_snapshot_folder nvarchar(255) null
  21953.         end
  21954.  
  21955.         /*
  21956.          * Snapshot pre/post commands
  21957.         */
  21958.         if not exists (select * from syscolumns where id = object_id('syspublications') and name = 'pre_snapshot_script')
  21959.         begin
  21960.             alter table syspublications add pre_snapshot_script nvarchar(255) null
  21961.         end
  21962.        
  21963.         if not exists (select * from syscolumns where id = object_id('syspublications') and name = 'post_snapshot_script')
  21964.         begin
  21965.             alter table syspublications add post_snapshot_script nvarchar(255) null
  21966.         end
  21967.  
  21968.         /*
  21969.          * Snapshot compression
  21970.         */
  21971.         if not exists (select * from syscolumns where id = object_id('syspublications') and name = 'compress_snapshot')
  21972.         begin
  21973.             alter table syspublications add compress_snapshot bit default 0 not null
  21974.         end
  21975.  
  21976.         /*
  21977.          * Post SQL7.0 FTP configuration stored at publisher
  21978.         */
  21979.         if not exists (select * from syscolumns where id = object_id('syspublications') and name = 'ftp_address')
  21980.         begin
  21981.             alter table syspublications add ftp_address sysname null
  21982.         end
  21983.  
  21984.         if not exists (select * from syscolumns where id = object_id('syspublications') and name = 'ftp_port')
  21985.         begin
  21986.             alter table syspublications add ftp_port int not null default 21
  21987.         end
  21988.  
  21989.         if not exists (select * from syscolumns where id = object_id('syspublications') and name = 'ftp_subdirectory')
  21990.         begin
  21991.             alter table syspublications add ftp_subdirectory nvarchar(255) null
  21992.         end
  21993.  
  21994.         if not exists (select * from syscolumns where id = object_id('syspublications') and name = 'ftp_login')
  21995.         begin
  21996.             alter table syspublications add ftp_login sysname null default N'anonymous'
  21997.         end
  21998.  
  21999.         if not exists (select * from syscolumns where id = object_id('syspublications') and name = 'ftp_password')
  22000.         begin
  22001.             alter table syspublications add ftp_password nvarchar(524) null
  22002.         end
  22003.  
  22004.         /*
  22005.          * Transformable subscriptions
  22006.         */
  22007.         if not exists (select * from syscolumns where id = object_id('syspublications') and 
  22008.             name = 'allow_dts')
  22009.         begin
  22010.             alter table syspublications add allow_dts bit default 0 not null
  22011.         end
  22012.  
  22013.         /*
  22014.          * Attach & Go 
  22015.         */
  22016.         if not exists (select * from syscolumns where id = object_id('syspublications') and 
  22017.             name = 'allow_subscription_copy')
  22018.         begin
  22019.             alter table syspublications add allow_subscription_copy bit default 0 not null
  22020.         end
  22021.  
  22022.         /*
  22023.          * Transactional conflict management
  22024.         */
  22025.         if not exists (select * from syscolumns where id = object_id('syspublications') and 
  22026.             name = 'centralized_conflicts')
  22027.         begin
  22028.             alter table syspublications add centralized_conflicts bit NULL
  22029.         end
  22030.     
  22031.         if not exists (select * from syscolumns where id = object_id('syspublications') and 
  22032.             name = 'conflict_retention')
  22033.         begin
  22034.             alter table syspublications add conflict_retention int NULL
  22035.         end
  22036.  
  22037.         if not exists (select * from syscolumns where id = object_id('syspublications') and 
  22038.             name = 'conflict_policy')
  22039.         begin
  22040.             alter table syspublications add conflict_policy int NULL
  22041.         end
  22042.  
  22043.         /*
  22044.          * Attach & Go 
  22045.         */
  22046.         if not exists (select * from syscolumns where id = object_id('syspublications') and 
  22047.             name = 'queue_type')
  22048.         begin
  22049.             alter table syspublications add queue_type int NULL
  22050.         end
  22051.  
  22052.         /*
  22053.          * Active Directory
  22054.         */
  22055.         if not exists (select * from syscolumns where id = object_id('syspublications') and 
  22056.             name = 'ad_guidname')
  22057.         begin
  22058.             alter table syspublications add ad_guidname sysname null
  22059.         end
  22060.  
  22061.         if not exists (select * from syscolumns where id = object_id('syspublications') and 
  22062.             name = 'backward_comp_level')
  22063.         begin
  22064.             alter table syspublications add backward_comp_level int default 10 not null
  22065.         end
  22066.         
  22067.         /*
  22068.          * Schema only articles (views, procs, udfs)
  22069.         */
  22070.         if not exists (select * from sysobjects where name = 'sysschemaarticles')
  22071.         begin
  22072.             create table dbo.sysschemaarticles
  22073.             (
  22074.                 artid               int                 NOT NULL,
  22075.                 creation_script     nvarchar(255)       NULL,
  22076.                 description         nvarchar(255)       NULL,
  22077.                 dest_object         sysname             NOT NULL,
  22078.                 name                sysname             NOT NULL,
  22079.                 objid               int                 NOT NULL,
  22080.                 pubid               int                 NOT NULL,
  22081.                 pre_creation_cmd    tinyint             NOT NULL,
  22082.                 status              int                 NOT NULL,
  22083.                 type                tinyint             NOT NULL,
  22084.                 schema_option       binary(8)           NULL,
  22085.                 dest_owner          sysname             NULL
  22086.             )
  22087.             exec dbo.sp_MS_marksystemobject sysschemaarticles
  22088.  
  22089.             if not exists (select * from sysindexes where name = 'unc1sysschemaarticles')
  22090.             begin
  22091.                 create unique nonclustered index unc1sysschemaarticles
  22092.                     on sysschemaarticles(artid, pubid)
  22093.             end  
  22094.  
  22095.         end
  22096.  
  22097.         if exists (select * from sysobjects where name = 'sysextendedarticlesview')
  22098.         begin
  22099.             drop view dbo.sysextendedarticlesview
  22100.         end
  22101.         -- cannot create view directly in stored procedure            
  22102.         exec ( 'create view dbo.sysextendedarticlesview
  22103.                    as
  22104.                    select artid, columns, creation_script, del_cmd, description,
  22105.                    dest_table, filter, filter_clause, ins_cmd, name, objid, pubid, pre_creation_cmd,
  22106.                    status, sync_objid, type, upd_cmd, schema_option, dest_owner    
  22107.                    from sysarticles
  22108.                    union all
  22109.                    select artid, NULL, creation_script, NULL, description,
  22110.                    dest_object, NULL, NULL, NULL, name, objid, pubid, 
  22111.                    pre_creation_cmd, status, NULL, type, NULL, 
  22112.                    schema_option, dest_owner 
  22113.                    from sysschemaarticles' )
  22114.  
  22115.         exec dbo.sp_MS_marksystemobject 'sysextendedarticlesview'
  22116.  
  22117.         exec sp_vupgrade_syscol_status
  22118.  
  22119.     end
  22120.  
  22121.     -- sysarticleupdates
  22122.     if exists (select name from sysobjects where name='sysarticleupdates')
  22123.     begin
  22124.         if not exists (select * from syscolumns where id = object_id('sysarticleupdates') and 
  22125.             name = 'sync_upd_trig')
  22126.         begin
  22127.             alter table sysarticleupdates add sync_upd_trig int default 0 NOT NULL
  22128.         end
  22129.  
  22130.         if not exists (select * from syscolumns where id = object_id('sysarticleupdates') and 
  22131.             name = 'conflict_tableid')
  22132.         begin
  22133.             alter table sysarticleupdates add conflict_tableid int NULL
  22134.         end
  22135.  
  22136.         if not exists (select * from syscolumns where id = object_id('sysarticleupdates') and 
  22137.             name = 'ins_conflict_proc')
  22138.         begin
  22139.             alter table sysarticleupdates add ins_conflict_proc int NULL
  22140.         end
  22141.  
  22142.         if not exists (select * from syscolumns where id = object_id('sysarticleupdates') and 
  22143.             name = 'identity_support')
  22144.         begin
  22145.             alter table sysarticleupdates add identity_support bit default 0 NOT NULL
  22146.         end
  22147.  
  22148.     end
  22149.  
  22150.     -- Upgrade dbt->distbackuplsn
  22151.     -- Make sure the upgrade is done for 8.0 Beta 2 customers.
  22152.     if exists (select * from sysobjects where name = 'sysarticles') and
  22153.         not exists (select * from sysobjects where name = 'systranschemas')
  22154.     begin
  22155.         -- Force to get in even if the logreader is running.
  22156.         exec sp_replflush 
  22157.         exec sp_repldone @xactid = NULL, @xact_segno = NULL, @numtrans = 0,
  22158.             @time = 0, @reset = 0, @code = 1
  22159.         -- Unmark the connection as the logreader.
  22160.         exec sp_replflush
  22161.     end
  22162.  
  22163.     -- Create new tran tables if the db is enabled for tran publishing.
  22164.     if exists (select name from sysobjects where name='syspublications')
  22165.     begin
  22166.         exec dbo.sp_MScreate_pub_tables
  22167.     end
  22168.  
  22169.     /*
  22170.      * syspublications
  22171.     */
  22172.     if exists (select name from sysobjects where name='syspublications')
  22173.     begin
  22174.         if not exists (select * from syscolumns where id = Object_Id('syspublications') and name = 'ftp_password' and length = '1048')
  22175.         begin
  22176.             /*
  22177.              * syspublications ftp_password
  22178.              * no need to upgrade passwords since this column is new in 8.0.
  22179.             */
  22180.             declare @dbname sysname
  22181.             declare @cmptlevel tinyint
  22182.             set @dbname = db_name()
  22183.             select @cmptlevel = cmptlevel from master..sysdatabases where name = @dbname collate database_default
  22184.             if @cmptlevel < 70
  22185.             begin
  22186.                                 raiserror (15048, -1, -1, 70, 70, 70, 80)
  22187.             end
  22188.             else
  22189.             begin
  22190.                 exec( 'alter table syspublications alter column ftp_password nvarchar(524)' )
  22191.             end
  22192.         end
  22193.  
  22194.         -- change non-clustered index on syspublications.pubid to clustered 
  22195.         -- index
  22196.         if exists( select * from sysindexes where name = 'unc1syspublications' and id = object_id('dbo.syspublications') )
  22197.         begin
  22198.            drop index dbo.syspublications.unc1syspublications 
  22199.         end
  22200.         if not exists ( select * from sysindexes where name = 'uc1syspublications' and id = object_id('dbo.syspublications') )
  22201.         begin
  22202.             create unique clustered index uc1syspublications
  22203.                 on syspublications (pubid)
  22204.         end
  22205.     end
  22206. end
  22207. go
  22208. exec dbo.sp_MS_marksystemobject sp_vupgrade_publisherdb
  22209. go
  22210.  
  22211. raiserror('Creating procedure sp_vupgrade_replmsdb', 0,1)
  22212. go
  22213. create procedure sp_vupgrade_replmsdb 
  22214. as
  22215. begin
  22216. /* 
  22217.  * Process schema and metadata changes specific to a msdb database. Updates datatype
  22218.  * mappings for heterogeneous replication.
  22219.  *
  22220.  * Setup version upgrade procedure call order:
  22221.  *    sp_vupgrade_replication -> sp_vupgrade_replmsdb (only called at distributors)
  22222. */
  22223.  
  22224.     set nocount on 
  22225.  
  22226.     declare @retcode int
  22227.             ,@profile_id int
  22228.             ,@table_name sysname
  22229.             ,@profile_name nvarchar(100)
  22230.             ,@profile_desc nvarchar(100)
  22231.  
  22232.     -- raiserror('sp_vupgrade_replmsdb', 0,1)
  22233.     
  22234.     -- Drop and regenerate agent parameters and associated values from system profiles.
  22235.     select @profile_id = 1
  22236.     while (@profile_id < 8)
  22237.     begin
  22238.  
  22239.         exec @retcode = dbo.sp_drop_agent_parameter @profile_id
  22240.         if (@retcode = 1)
  22241.             return (1)
  22242.  
  22243.         exec @retcode = dbo.sp_generate_agent_parameter @profile_id
  22244.         if (@retcode = 1)
  22245.             return (1)
  22246.  
  22247.         select @profile_id = @profile_id + 1
  22248.  
  22249.     end
  22250.     
  22251.     declare hUserProfile CURSOR LOCAL FAST_FORWARD FOR
  22252.         select distinct profile_id from msdb..MSagent_profiles where profile_id >= 8 for read only   
  22253.     open hUserProfile 
  22254.     fetch hUserProfile into @profile_id
  22255.  
  22256.     while @@fetch_status <> -1
  22257.         begin
  22258.         exec @retcode = dbo.sp_drop_agent_parameter @profile_id, @parameter_name = '-ReadBatchThreshold'
  22259.         if (@retcode = 1)
  22260.         begin
  22261.             close hUserProfile 
  22262.             deallocate hUserProfile 
  22263.                 return (1)
  22264.         end
  22265.  
  22266.         fetch hUserProfile into @profile_id
  22267.         end    
  22268.         close hUserProfile 
  22269.         deallocate hUserProfile 
  22270.  
  22271.     --
  22272.     -- Add 8.0 agent profiles
  22273.     --
  22274.  
  22275.     /* 
  22276.     ** Distribution agent : Synchronization Manager Profile
  22277.     */
  22278.     select @profile_id = NULL
  22279.         ,@profile_name = formatmessage(20550) -- Dist SyncMgr Profile
  22280.         ,@profile_desc = formatmessage(20551)
  22281.     select @profile_id = profile_id from msdb..MSagent_profiles 
  22282.         where agent_type = 3 and profile_name = @profile_name
  22283.     if (@profile_id is null)
  22284.     begin
  22285.         --
  22286.         -- Add profile
  22287.         --
  22288.         select @profile_id = NULL
  22289.  
  22290.         exec @retcode = dbo.sp_add_agent_profile
  22291.                 @profile_id = @profile_id OUT,
  22292.                 @profile_name = @profile_name,
  22293.                 @agent_type = 3,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
  22294.                 @profile_type = 0,   -- 0-System, 1-Custom 
  22295.                 @description = @profile_desc,
  22296.                 @default = 0
  22297.         if (@retcode = 1 or @@ERROR <> 0)
  22298.             return (1)
  22299.     end
  22300.     else
  22301.     begin
  22302.         --
  22303.         -- Profile exists - drop the parameters for regeneration
  22304.         --
  22305.         exec @retcode = dbo.sp_drop_agent_parameter @profile_id
  22306.         if (@retcode = 1)
  22307.             return (1)
  22308.     end
  22309.     exec @retcode = dbo.sp_generate_agent_parameter 
  22310.         @profile_id = 10,
  22311.         @real_profile_id = @profile_id
  22312.     if (@retcode = 1 or @@ERROR <> 0)
  22313.         return (1)
  22314.  
  22315.  
  22316.     -- Queue default profile
  22317.     select @profile_id = NULL
  22318.     select @profile_id = profile_id from msdb..MSagent_profiles 
  22319.         where agent_type = 9 and def_profile = 1
  22320.     if (@profile_id is null)
  22321.     begin
  22322.         --
  22323.         -- Add profile
  22324.         --
  22325.         select @profile_id = NULL
  22326.                 ,@profile_name = formatmessage(20545) -- Default QueueReader Profile
  22327.                 ,@profile_desc = formatmessage(20589)
  22328.  
  22329.         exec @retcode = dbo.sp_add_agent_profile
  22330.             @profile_id = @profile_id OUT,
  22331.             @profile_name = @profile_name,
  22332.             @agent_type = 9,
  22333.             @profile_type = 0, 
  22334.             @description = @profile_desc,
  22335.             @default = 1
  22336.         if (@retcode = 1 or @@ERROR <> 0)
  22337.             return (1)
  22338.     end
  22339.     else
  22340.     begin
  22341.         --
  22342.         -- Profile exists - drop the parameters for regeneration
  22343.         --
  22344.         exec @retcode = dbo.sp_drop_agent_parameter @profile_id
  22345.         if (@retcode = 1)
  22346.             return (1)
  22347.     end
  22348.     exec @retcode = dbo.sp_generate_agent_parameter 
  22349.         @profile_id = 11,
  22350.         @real_profile_id = @profile_id
  22351.     if (@retcode = 1 or @@ERROR <> 0)
  22352.         return (1)
  22353.  
  22354.     --
  22355.     -- Add 'skip data consistency error' profile
  22356.     --
  22357.     select @profile_id = NULL
  22358.         ,@profile_name = formatmessage(20599) -- Default Distribution Profile
  22359.         ,@profile_desc = formatmessage(20600)
  22360.     select @profile_id = profile_id from msdb..MSagent_profiles 
  22361.         where agent_type = 3 and profile_name = @profile_name
  22362.     if (@profile_id is null)
  22363.     begin
  22364.         --
  22365.         -- Add profile
  22366.         --
  22367.         select @profile_id = NULL
  22368.  
  22369.         exec @retcode = dbo.sp_add_agent_profile
  22370.                 @profile_id = @profile_id OUT,
  22371.                 @profile_name = @profile_name,
  22372.                 @agent_type = 3,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
  22373.                 @profile_type = 0,   -- 0-System, 1-Custom 
  22374.                 @description = @profile_desc,
  22375.                 @default = 0
  22376.         if (@retcode = 1 or @@ERROR <> 0)
  22377.             return (1)
  22378.     end
  22379.     else
  22380.     begin
  22381.         --
  22382.         -- Profile exists - drop the parameters for regeneration
  22383.         --
  22384.         exec @retcode = dbo.sp_drop_agent_parameter @profile_id
  22385.         if (@retcode = 1)
  22386.             return (1)
  22387.     end
  22388.     exec @retcode = dbo.sp_generate_agent_parameter 
  22389.         @profile_id = 14,
  22390.         @real_profile_id = @profile_id
  22391.     if (@retcode = 1 or @@ERROR <> 0)
  22392.         return (1)
  22393.         
  22394.     /* 
  22395.     ** Merge agent : Non default profile for disconnected scenarios ( unreliable link ) 
  22396.     */
  22397.     set @profile_id = NULL
  22398.     set @profile_name = formatmessage(20548) -- Non-Default Merge Profile
  22399.     set @profile_desc = formatmessage(20549)
  22400.  
  22401.     select @profile_id = profile_id from msdb..MSagent_profiles where agent_type = 4 and profile_name = @profile_name
  22402.     if (@profile_id is null)
  22403.     begin
  22404.         exec @retcode = dbo.sp_add_agent_profile
  22405.             @profile_id = @profile_id OUT,
  22406.             @profile_name = @profile_name,
  22407.             @agent_type = 4,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
  22408.             @profile_type = 0,   -- 0-System, 1-Custom 
  22409.             @description = @profile_desc,
  22410.             @default = 0
  22411.     end
  22412.     else
  22413.     begin
  22414.         --
  22415.         -- Profile exists - drop the parameters for regeneration
  22416.         --
  22417.         exec @retcode = dbo.sp_drop_agent_parameter @profile_id
  22418.         if (@retcode = 1)
  22419.             return (1)
  22420.     end
  22421.  
  22422.     exec @retcode = dbo.sp_generate_agent_parameter 7, @profile_id
  22423.     if (@retcode = 1 or @@ERROR <> 0)
  22424.         return (1)
  22425.  
  22426.     /* 
  22427.     ** Merge agent : Non default profile for verbose histroy
  22428.     */
  22429.     set @profile_id = NULL
  22430.     set @profile_name = formatmessage(20546) -- Verbose Merge Profile
  22431.     set @profile_desc = formatmessage(20547)
  22432.  
  22433.     select @profile_id = profile_id from msdb..MSagent_profiles where agent_type = 4 and profile_name = @profile_name
  22434.     if (@profile_id is null)
  22435.     begin
  22436.         exec @retcode = dbo.sp_add_agent_profile
  22437.             @profile_id = @profile_id OUT,
  22438.             @profile_name = @profile_name,
  22439.             @agent_type = 4,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
  22440.             @profile_type = 0,   -- 0-System, 1-Custom 
  22441.             @description = @profile_desc,
  22442.             @default = 0
  22443.     end
  22444.     else
  22445.     begin
  22446.         --
  22447.         -- Profile exists - drop the parameters for regeneration
  22448.         --
  22449.         exec @retcode = dbo.sp_drop_agent_parameter @profile_id
  22450.         if (@retcode = 1)
  22451.             return (1)
  22452.     end
  22453.  
  22454.     exec @retcode = dbo.sp_generate_agent_parameter 8, @profile_id
  22455.     if (@retcode = 1 or @@ERROR <> 0)
  22456.         return (1)
  22457.  
  22458.     /* 
  22459.     ** Merge agent : Synchronization Manager Profile
  22460.     */
  22461.     set @profile_id = NULL
  22462.     set @profile_name = formatmessage(20550) -- SyncMgr Profile
  22463.     set @profile_desc = formatmessage(20551)
  22464.  
  22465.     select @profile_id = profile_id from msdb..MSagent_profiles where agent_type = 4 and profile_name = @profile_name
  22466.     if (@profile_id is null)
  22467.     begin
  22468.         exec @retcode = dbo.sp_add_agent_profile
  22469.             @profile_id = @profile_id OUT,
  22470.             @profile_name = @profile_name,
  22471.             @agent_type = 4,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
  22472.             @profile_type = 0,   -- 0-System, 1-Custom 
  22473.             @description = @profile_desc,
  22474.             @default = 0
  22475.     end
  22476.     else
  22477.     begin
  22478.         --
  22479.         -- Profile exists - drop the parameters for regeneration
  22480.         --
  22481.         exec @retcode = dbo.sp_drop_agent_parameter @profile_id
  22482.         if (@retcode = 1)
  22483.             return (1)
  22484.     end
  22485.  
  22486.     exec @retcode = dbo.sp_generate_agent_parameter 9, @profile_id
  22487.     if (@retcode = 1 or @@ERROR <> 0)
  22488.         return (1)
  22489.  
  22490.      /* 
  22491.     ** Merge agent : Rowcount Validation profile  
  22492.     */
  22493.     set @profile_id = NULL
  22494.     set @profile_name = formatmessage(21308) -- Rowcount Validation Profile
  22495.     set @profile_desc = formatmessage(21309) -- Rowcount Validation Profile Description
  22496.  
  22497.     select @profile_id = profile_id from msdb..MSagent_profiles where agent_type = 4 and profile_name = @profile_name
  22498.     if (@profile_id is null)
  22499.     begin
  22500.         exec @retcode = dbo.sp_add_agent_profile
  22501.             @profile_id = @profile_id OUT,
  22502.             @profile_name = @profile_name,
  22503.             @agent_type = 4,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
  22504.             @profile_type = 0,   -- 0-System, 1-Custom 
  22505.             @description = @profile_desc,
  22506.             @default = 0
  22507.     end
  22508.     else
  22509.     begin
  22510.         --
  22511.         -- Profile exists - drop the parameters for regeneration
  22512.         --
  22513.         exec @retcode = dbo.sp_drop_agent_parameter @profile_id
  22514.         if (@retcode = 1)
  22515.             return (1)
  22516.     end
  22517.  
  22518.     exec @retcode = dbo.sp_generate_agent_parameter 12, @profile_id
  22519.     if (@retcode = 1 or @@ERROR <> 0)
  22520.         return (1)
  22521.  
  22522.     /* 
  22523.     ** Merge agent : Rowcount & Checksum Validation profile  
  22524.     */
  22525.     set @profile_id = NULL
  22526.     set @profile_name = formatmessage(21310) -- Rowcount & Checksum Validation Profile
  22527.     set @profile_desc = formatmessage(21311) -- Rowcount & Checksum Validation Profile Description
  22528.     
  22529.     select @profile_id = profile_id from msdb..MSagent_profiles where agent_type = 4 and profile_name = @profile_name
  22530.     if (@profile_id is null)
  22531.     begin
  22532.         exec @retcode = dbo.sp_add_agent_profile
  22533.             @profile_id = @profile_id OUT,
  22534.             @profile_name = @profile_name,
  22535.             @agent_type = 4,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
  22536.             @profile_type = 0,   -- 0-System, 1-Custom 
  22537.             @description = @profile_desc,
  22538.             @default = 0
  22539.     end
  22540.     else
  22541.     begin
  22542.         --
  22543.         -- Profile exists - drop the parameters for regeneration
  22544.         --
  22545.         exec @retcode = dbo.sp_drop_agent_parameter @profile_id
  22546.         if (@retcode = 1)
  22547.             return (1)
  22548.     end
  22549.  
  22550.     exec @retcode = dbo.sp_generate_agent_parameter 13, @profile_id
  22551.     if (@retcode = 1 or @@ERROR <> 0)
  22552.         return (1)
  22553.  
  22554.     /* 
  22555.     ** Merge agent : High volume server-to-server profile
  22556.     */
  22557.     set @profile_id = NULL
  22558.     set @profile_name = formatmessage(20616) -- High volume server-to-server profile
  22559.     set @profile_desc = formatmessage(20617) -- High volume server-to-server profile Description
  22560.  
  22561.     select @profile_id = profile_id from msdb..MSagent_profiles where agent_type = 4 and profile_name = @profile_name
  22562.     if (@profile_id is null)
  22563.     begin
  22564.         exec @retcode = dbo.sp_add_agent_profile
  22565.             @profile_id = @profile_id OUT,
  22566.             @profile_name = @profile_name,
  22567.             @agent_type = 4,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
  22568.             @profile_type = 0,   -- 0-System, 1-Custom 
  22569.             @description = @profile_desc,
  22570.             @default = 0
  22571.     end
  22572.     else
  22573.     begin
  22574.         --
  22575.         -- Profile exists - drop the parameters for regeneration
  22576.         --
  22577.         exec @retcode = dbo.sp_drop_agent_parameter @profile_id
  22578.         if (@retcode = 1)
  22579.             return (1)
  22580.     end
  22581.  
  22582.     exec @retcode = dbo.sp_generate_agent_parameter 15, @profile_id
  22583.     if (@retcode = 1 or @@ERROR <> 0)
  22584.         return (1)
  22585.  
  22586.     -- Add MSdatatype_mappings table and default mappings
  22587.     if not exists( select * from msdb..sysobjects where name = 'MSdatatype_mappings' 
  22588.         and xtype = 'U')
  22589.     begin
  22590.         create table msdb.dbo.MSdatatype_mappings 
  22591.         (
  22592.         dbms_name           sysname NOT NULL,
  22593.         sql_type            sysname NOT NULL,
  22594.         dest_type           sysname NOT NULL,
  22595.         dest_prec           int     NOT NULL,
  22596.         dest_create_params  int     NOT NULL,
  22597.         dest_nullable       bit     NOT NULL
  22598.         )
  22599.  
  22600.         -- MS Jet
  22601.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'binary' , 'binary', 255, 4, 1
  22602.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'varbinary' , 'varbinary', 255, 4, 1
  22603.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'binary' , 'image', 1073741824, 0, 1
  22604.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'varbinary' , 'image', 1073741824, 0, 1
  22605.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'sql_variant' , 'longtext', 1073741824, 0, 1
  22606.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'varchar' , 'varchar', 255, 4, 1
  22607.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'varchar' , 'longtext', 1073741824, 0, 1
  22608.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'nchar' , 'nchar', 255, 4, 1
  22609.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'nchar' , 'longtext', 1073741824, 0, 1
  22610.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'char' , 'char', 255, 4, 1
  22611.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'char' , 'longtext', 1073741824, 0, 1
  22612.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'nvarchar' , 'nchar varying', 255, 4, 1
  22613.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'nvarchar' , 'longtext', 1073741824, 0, 1
  22614.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'datetime' , 'datetime', 255, 0, 1
  22615.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'smalldatetime' , 'datetime', 255, 0, 1
  22616.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'decimal' , 'decimal', 255, 3, 1
  22617.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'numeric' , 'decimal', 255, 3, 1
  22618.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'float' , 'float', 255, 0, 1
  22619.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'real' , 'real', 255, 0, 1
  22620.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'bigint' , 'decimal', 255, 0, 1
  22621.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'int' , 'int', 255, 0, 1
  22622.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'smallint' , 'smallint', 255, 0, 1
  22623.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'tinyint' , 'byte', 255, 0, 1
  22624.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'money' , 'currency', 255, 0, 1
  22625.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'smallmoney' , 'currency', 255, 0, 1
  22626.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'bit' , 'bit', 255, 0, 1
  22627.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'sysname' , 'nchar varying', 255, 4, 1
  22628.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'timestamp' , 'binary', 255, 4, 1
  22629.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'uniqueidentifier' , 'guid', 255, 0, 1
  22630.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'text' , 'longtext', 1073741824, 0, 1
  22631.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'ntext' , 'longtext', 1073741824, 0, 1
  22632.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'image' , 'image', 1073741824, 0, 1
  22633.  
  22634.         -- Oracle
  22635.         exec dbo.sp_add_datatype_mapping 'Oracle', 'binary' , 'raw', 255, 4, 1
  22636.         exec dbo.sp_add_datatype_mapping 'Oracle', 'varbinary' , 'raw', 255, 4, 1
  22637.         exec dbo.sp_add_datatype_mapping 'Oracle', 'binary' , 'long raw', 2147483647, 0, 1
  22638.         exec dbo.sp_add_datatype_mapping 'Oracle', 'varbinary' , 'long raw', 2147483647, 0, 1
  22639.         exec dbo.sp_add_datatype_mapping 'Oracle', 'sql_variant' , 'long', 2147483647, 0, 1
  22640.         --exec dbo.sp_add_datatype_mapping 'Oracle', 'varchar' , 'char', 255, 4, 1
  22641.         exec dbo.sp_add_datatype_mapping 'Oracle', 'varchar' , 'varchar2', 2000, 4, 1
  22642.         exec dbo.sp_add_datatype_mapping 'Oracle', 'varchar' , 'long', 2147483647, 0, 1
  22643.         exec dbo.sp_add_datatype_mapping 'Oracle', 'nchar' , 'char', 255, 4, 1
  22644.         exec dbo.sp_add_datatype_mapping 'Oracle', 'nchar' , 'varchar2', 2000, 4, 1
  22645.         exec dbo.sp_add_datatype_mapping 'Oracle', 'nchar' , 'long', 2147483647, 0, 1
  22646.         exec dbo.sp_add_datatype_mapping 'Oracle', 'char' , 'char', 255, 4, 1
  22647.         exec dbo.sp_add_datatype_mapping 'Oracle', 'char' , 'varchar2', 2000, 4, 1
  22648.         exec dbo.sp_add_datatype_mapping 'Oracle', 'char' , 'long', 2147483647, 0, 1
  22649.         --exec dbo.sp_add_datatype_mapping 'Oracle', 'nvarchar' , 'char', 255, 4, 1
  22650.         exec dbo.sp_add_datatype_mapping 'Oracle', 'nvarchar' , 'varchar2', 2000, 4, 1
  22651.         exec dbo.sp_add_datatype_mapping 'Oracle', 'nvarchar' , 'long', 2147483647, 0, 1
  22652.         exec dbo.sp_add_datatype_mapping 'Oracle', 'datetime' , 'date', 255, 0, 1
  22653.         exec dbo.sp_add_datatype_mapping 'Oracle', 'smalldatetime' , 'date', 255, 0, 1
  22654.         exec dbo.sp_add_datatype_mapping 'Oracle', 'decimal' , 'number', 255, 3, 1
  22655.         exec dbo.sp_add_datatype_mapping 'Oracle', 'numeric' , 'number', 255, 3, 1
  22656.         exec dbo.sp_add_datatype_mapping 'Oracle', 'float' , 'float', 255, 0, 1
  22657.         exec dbo.sp_add_datatype_mapping 'Oracle', 'real' , 'float', 255, 0, 1
  22658.         exec dbo.sp_add_datatype_mapping 'Oracle', 'bigint' , 'number', 255, 3, 1
  22659.         exec dbo.sp_add_datatype_mapping 'Oracle', 'int' , 'number', 255, 3, 1
  22660.         exec dbo.sp_add_datatype_mapping 'Oracle', 'smallint' , 'number', 255, 3, 1
  22661.         exec dbo.sp_add_datatype_mapping 'Oracle', 'tinyint' , 'number', 255, 3, 1
  22662.         exec dbo.sp_add_datatype_mapping 'Oracle', 'money' , 'number', 255, 3, 1
  22663.         exec dbo.sp_add_datatype_mapping 'Oracle', 'smallmoney' , 'number', 255, 3, 1
  22664.         exec dbo.sp_add_datatype_mapping 'Oracle', 'bit' , 'number', 255, 3, 1
  22665.         exec dbo.sp_add_datatype_mapping 'Oracle', 'sysname' , 'char', 255, 4, 1
  22666.         exec dbo.sp_add_datatype_mapping 'Oracle', 'timestamp' , 'raw', 255, 4, 1
  22667.         exec dbo.sp_add_datatype_mapping 'Oracle', 'uniqueidentifier' , 'char', 255, 4, 1
  22668.         exec dbo.sp_add_datatype_mapping 'Oracle', 'text' , 'long', 2147483647, 0, 1
  22669.         exec dbo.sp_add_datatype_mapping 'Oracle', 'ntext' , 'long', 2147483647, 0, 1
  22670.         exec dbo.sp_add_datatype_mapping 'Oracle', 'image' , 'long raw', 2147483647, 0, 1
  22671.  
  22672.         -- MS SSCE
  22673.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'binary' , 'binary', 255, 4, 1
  22674.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'varbinary' , 'varbinary', 255, 4, 1
  22675.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'binary' , 'image', 1073741824, 0, 1
  22676.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'varbinary' , 'image', 1073741824, 0, 1
  22677.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'sql_variant' , 'ntext', 1073741824, 0, 1
  22678.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'varchar' , 'national char varying', 255, 4, 1
  22679.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'varchar' , 'ntext', 1073741824, 0, 1
  22680.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'nchar' , 'nchar', 255, 4, 1
  22681.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'nchar' , 'ntext', 1073741824, 0, 1
  22682.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'char' , 'nchar', 255, 4, 1
  22683.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'char' , 'ntext', 1073741824, 0, 1
  22684.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'nvarchar' , 'national char varying', 255, 4, 1
  22685.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'nvarchar' , 'ntext', 1073741824, 0, 1
  22686.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'datetime' , 'datetime', 255, 0, 1
  22687.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'smalldatetime' , 'datetime', 255, 0, 1
  22688.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'decimal' , 'numeric', 255, 3, 1
  22689.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'numeric' , 'numeric', 255, 3, 1
  22690.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'float' , 'float', 255, 0, 1
  22691.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'real' , 'real', 255, 0, 1
  22692.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'bigint' , 'bigint', 255, 0, 1
  22693.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'int' , 'int', 255, 0, 1
  22694.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'smallint' , 'smallint', 255, 0, 1
  22695.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'tinyint' , 'tinyint', 255, 0, 1
  22696.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'money' , 'money', 255, 0, 1
  22697.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'smallmoney' , 'money', 255, 0, 1
  22698.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'bit' , 'bit', 255, 0, 1
  22699.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'sysname' , 'national char varying', 255, 4, 1
  22700.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'timestamp' , 'binary', 255, 4, 1
  22701.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'uniqueidentifier' , 'uniqueidentifier', 255, 0, 1
  22702.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'text' , 'ntext', 1073741824, 0, 1
  22703.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'ntext' , 'ntext', 1073741824, 0, 1
  22704.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'image' , 'image', 1073741824, 0, 1
  22705.  
  22706.         --DB2/400
  22707.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'bit', 'SMALLINT', 1,  0, 1
  22708.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'tinyint', 'SMALLINT', 1, 0, 1
  22709.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'smallint', 'SMALLINT', 5, 0, 1
  22710.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'int', 'INT', 10, 0, 1
  22711.  
  22712.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'char', 'CHAR', 8000, 4, 1
  22713.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'varchar', 'VARCHAR', 8000, 4, 1
  22714.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'smalldatetime', 'TIMESTAMP', 26, 0, 1
  22715.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'datetime', 'TIMESTAMP', 26, 0, 1
  22716.  
  22717.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'real', 'REAL', 24, 0, 1
  22718.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'decimal', 'DECIMAL', 31, 3, 1
  22719.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'double precision', 'DOUBLE', 53, 0, 1
  22720.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'float', 'FLOAT', 53, 0, 1
  22721.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'numeric', 'NUMERIC', 31, 3, 1
  22722.  
  22723.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'smallmoney', 'DECIMAL', 10, 3, 1
  22724.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'money', 'DECIMAL', 19, 3, 1
  22725.  
  22726.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'varbinary', 'VARCHAR () FOR BIT DATA', 8000, 4, 1
  22727.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'binary', 'CHAR () FOR BIT DATA', 8000, 4, 1
  22728.  
  22729.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'timestamp', 'CHAR () FOR BIT DATA', 8, 4, 1
  22730.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'uniqueidentifier', 'CHAR', 38, 4, 1
  22731.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'image', 'VARCHAR () FOR BIT DATA', 32739, 4, 1
  22732.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'text', 'VARCHAR', 32739, 4, 1
  22733.  
  22734.         --DB2/MVS
  22735.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'bit', 'SMALLINT', 1,  0, 1
  22736.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'tinyint', 'SMALLINT', 1, 0, 1
  22737.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'smallint', 'SMALLINT', 5, 0, 1
  22738.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'int', 'INT', 10, 0, 1
  22739.  
  22740.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'char', 'CHAR', 254, 4, 1
  22741.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'varchar', 'VARCHAR', 4045, 4, 1
  22742.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'char', 'VARCHAR', 4045, 4, 1
  22743.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'smalldatetime', 'TIMESTAMP', 26, 0, 1
  22744.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'datetime', 'TIMESTAMP', 26, 0, 1
  22745.  
  22746.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'real', 'REAL', 24, 0, 1
  22747.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'decimal', 'DECIMAL', 31, 3, 1
  22748.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'double precision', 'DOUBLE', 53, 0, 1
  22749.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'float', 'FLOAT', 53, 0, 1
  22750.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'numeric', 'NUMERIC', 31, 3, 1
  22751.  
  22752.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'smallmoney', 'DECIMAL', 10, 3, 1
  22753.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'money', 'DECIMAL', 19, 3, 1
  22754.  
  22755.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'varbinary', 'VARCHAR () FOR BIT DATA', 4045, 4, 1
  22756.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'binary', 'CHAR () FOR BIT DATA', 254, 4, 1
  22757.  
  22758.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'timestamp', 'CHAR () FOR BIT DATA', 8, 4, 1
  22759.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'uniqueidentifier', 'CHAR', 38, 4, 1
  22760.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'image', 'VARCHAR () FOR BIT DATA', 4045, 4, 1
  22761.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'text', 'VARCHAR', 4045, 4, 1
  22762.  
  22763.         --DB2/NT
  22764.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'bit', 'SMALLINT', 1,  0, 1
  22765.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'tinyint', 'SMALLINT', 1, 0, 1
  22766.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'smallint', 'SMALLINT', 5, 0, 1
  22767.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'int', 'INT', 10, 0, 1
  22768.  
  22769.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'char', 'CHAR', 254, 4, 1
  22770.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'varchar', 'VARCHAR', 4000, 4, 1
  22771.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'char', 'VARCHAR', 4000, 4, 1
  22772.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'smalldatetime', 'TIMESTAMP', 26, 0, 1
  22773.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'datetime', 'TIMESTAMP', 26, 0, 1
  22774.  
  22775.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'real', 'REAL', 24, 0, 1
  22776.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'decimal', 'DECIMAL', 31, 3, 1
  22777.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'double precision', 'DOUBLE', 53, 0, 1
  22778.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'float', 'FLOAT', 53, 0, 1
  22779.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'numeric', 'NUMERIC', 31, 3, 1
  22780.  
  22781.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'smallmoney', 'DECIMAL', 10, 3, 1
  22782.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'money', 'DECIMAL', 19, 3, 1
  22783.  
  22784.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'varbinary', 'VARCHAR () FOR BIT DATA', 4000, 4, 1
  22785.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'binary', 'CHAR () FOR BIT DATA', 254, 4, 1
  22786.  
  22787.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'timestamp', 'CHAR () FOR BIT DATA', 8, 4, 1
  22788.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'uniqueidentifier', 'CHAR', 38, 4, 1
  22789.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'image', 'VARCHAR () FOR BIT DATA', 4000, 4, 1
  22790.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'text', 'VARCHAR', 4000, 4, 1
  22791.  
  22792.  
  22793.         --DB2/6000
  22794.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'bit', 'SMALLINT', 1,  0, 1
  22795.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'tinyint', 'SMALLINT', 1, 0, 1
  22796.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'smallint', 'SMALLINT', 5, 0, 1
  22797.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'int', 'INT', 10, 0, 1
  22798.  
  22799.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'char', 'CHAR', 254, 4, 1
  22800.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'varchar', 'VARCHAR', 4000, 4, 1
  22801.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'char', 'VARCHAR', 4000, 4, 1
  22802.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'smalldatetime', 'TIMESTAMP', 26, 0, 1
  22803.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'datetime', 'TIMESTAMP', 26, 0, 1
  22804.  
  22805.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'real', 'REAL', 24, 0, 1
  22806.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'decimal', 'DECIMAL', 31, 3, 1
  22807.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'double precision', 'DOUBLE', 53, 0, 1
  22808.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'float', 'FLOAT', 53, 0, 1
  22809.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'numeric', 'NUMERIC', 31, 3, 1
  22810.  
  22811.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'smallmoney', 'DECIMAL', 10, 3, 1
  22812.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'money', 'DECIMAL', 19, 3, 1
  22813.  
  22814.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'varbinary', 'VARCHAR () FOR BIT DATA', 4000, 4, 1
  22815.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'binary', 'CHAR () FOR BIT DATA', 254, 4, 1
  22816.  
  22817.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'timestamp', 'CHAR () FOR BIT DATA', 8, 4, 1
  22818.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'uniqueidentifier', 'CHAR', 38, 4, 1
  22819.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'image', 'VARCHAR () FOR BIT DATA', 4000, 4, 1
  22820.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'text', 'VARCHAR', 4000, 4, 1
  22821.  
  22822.     end
  22823.  
  22824.     /*
  22825.      * New indexes added starting with 7.0 sp1
  22826.     */
  22827.  
  22828.     --    MSdistpublishers
  22829.     select @table_name = N'MSdistpublishers'
  22830.     IF EXISTS ( SELECT * FROM msdb.dbo.sysobjects WHERE name = 'MSdistpublishers' ) 
  22831.     BEGIN
  22832.         IF EXISTS ( SELECT name
  22833.             FROM msdb.dbo.MSdistpublishers
  22834.             GROUP BY name 
  22835.             HAVING COUNT(*) > 1 )
  22836.             RAISERROR (21203, 10, 19, @table_name)
  22837.         ELSE
  22838.             IF NOT EXISTS ( SELECT * FROM msdb.dbo.sysindexes WHERE name = 'uc1MSdistpublishers' AND
  22839.                 id = OBJECT_ID('msdb.dbo.MSdistpublishers') )
  22840.                 CREATE UNIQUE CLUSTERED INDEX uc1MSdistpublishers ON msdb.dbo.MSdistpublishers(name)
  22841.  
  22842.     END
  22843.     
  22844.     --    MSdistributiondbs
  22845.     SELECT @table_name = N'MSdistributiondbs'
  22846.     IF EXISTS ( SELECT * FROM msdb.dbo.sysobjects WHERE name = 'MSdistributiondbs' )
  22847.     BEGIN
  22848.         IF EXISTS ( SELECT name
  22849.             FROM msdb.dbo.MSdistributiondbs
  22850.             GROUP BY name 
  22851.             HAVING COUNT(*) > 1 )
  22852.             RAISERROR (21203, 10, 20, @table_name)            
  22853.         ELSE                
  22854.             IF NOT EXISTS ( SELECT * FROM msdb.dbo.sysindexes WHERE name = 'uc1MSdistributiondbs' AND
  22855.                 id = OBJECT_ID('msdb.dbo.MSdistributiondbs') )
  22856.                 CREATE UNIQUE CLUSTERED INDEX uc1MSdistributiondbs ON msdb.dbo.MSdistributiondbs(name)
  22857.     END
  22858.     
  22859.     --    MSdistributor
  22860.     SELECT @table_name = N'MSdistributor'
  22861.     IF EXISTS ( SELECT * FROM msdb.dbo.sysobjects WHERE name = 'MSdistributor' )
  22862.     BEGIN
  22863.         IF EXISTS ( SELECT property
  22864.             FROM msdb.dbo.MSdistributor
  22865.             GROUP BY property 
  22866.             HAVING COUNT(*) > 1 )
  22867.             RAISERROR (21203, 10, 21, @table_name)            
  22868.         ELSE                    
  22869.             IF NOT EXISTS ( SELECT * FROM msdb.dbo.sysindexes WHERE name = 'uc1MSdistributor' AND
  22870.                 id = OBJECT_ID('msdb.dbo.MSdistributor') )
  22871.                 CREATE UNIQUE CLUSTERED INDEX uc1MSdistributor ON msdb.dbo.MSdistributor(property)
  22872.     END    
  22873.  
  22874.     /* 
  22875.      * Upgrade replication passwords in msdb database.
  22876.     */
  22877.     begin transaction
  22878.     /*
  22879.      * MSdistpublishers
  22880.     */
  22881.     if exists (select name from msdb.dbo.sysobjects where name='MSdistpublishers')
  22882.     begin
  22883.         if not exists (select * from msdb.dbo.syscolumns where id = Object_Id('msdb.dbo.MSdistpublishers') and name = 'password' and length = '1048')
  22884.         begin
  22885.             /*
  22886.              * alter password column from sysname to nvarchar(524)
  22887.             */
  22888.  
  22889.             alter table msdb.dbo.MSdistpublishers alter column password nvarchar(524)
  22890.         end
  22891.  
  22892.         /*
  22893.          * convert all the passwords to new encryption
  22894.          */
  22895.         declare @password nvarchar(524)
  22896.         declare cur_MSdistpublishers CURSOR LOCAL FORWARD_ONLY for 
  22897.             select password
  22898.             from msdb.dbo.MSdistpublishers
  22899.             for update of password
  22900.             
  22901.         open cur_MSdistpublishers
  22902.         fetch next from cur_MSdistpublishers into @password
  22903.         while ( @@fetch_status <> -1 )
  22904.         begin
  22905.             EXEC @retcode = master.dbo.xp_repl_convert_encrypt @password OUTPUT
  22906.             IF @@error <> 0 OR @retcode <> 0
  22907.             begin
  22908.                 rollback transaction
  22909.                 return 1
  22910.             end
  22911.  
  22912.             update msdb.dbo.MSdistpublishers
  22913.             set password=@password
  22914.             where current of cur_MSdistpublishers
  22915.  
  22916.             fetch next from cur_MSdistpublishers into @password
  22917.         end
  22918.     end
  22919.     commit transaction
  22920.  
  22921.     return (0)
  22922. end
  22923. go
  22924. exec dbo.sp_MS_marksystemobject sp_vupgrade_replmsdb
  22925. go
  22926.  
  22927. raiserror('Creating procedure sp_restoredbreplication', 0,1)
  22928. go
  22929.  
  22930. create procedure sp_restoredbreplication ( @srv_orig sysname, @db_orig sysname
  22931. ,@keep_replication int = 0 -- Make it int so that we can expand later.
  22932.  )
  22933. as 
  22934. /*
  22935.  * used by restore process to strip out replication settings if restoring to non-originating
  22936.  * server/db or system otherwise not capable of keeping replication working
  22937.  * WARNING : procs called here run internal to server and must be owner qualified
  22938. */
  22939. begin
  22940.  
  22941.     set nocount on
  22942.  
  22943.     -- db bits
  22944.     declare @db_tranbit int
  22945.     declare @db_mergbit int
  22946.     declare @db_distbit int
  22947.     select @db_tranbit = 1, @db_mergbit = 4, @db_distbit = 16
  22948.  
  22949.     declare @repl_installed bit -- repl procs installed flag
  22950.     declare @remove_repl bit    -- remove replication flag ; remove on true (1)
  22951.     declare @restoreoverride int
  22952.     declare @db_curr sysname
  22953.     DECLARE @retcode int
  22954.     DECLARE @proc nvarchar(255)
  22955.  
  22956.     -- Fixup lsns for dist db if needed
  22957.     -- This is to make sure that after the restore, the lsns are equal to or larger than
  22958.     -- the ones that have been sent to the publishers before the restore.
  22959.     -- reuse the procedures used by backup.
  22960.     exec @retcode = dbo.sp_MSrepl_backup_start
  22961.     if @retcode <> 0 or @@error <> 0
  22962.         return 0
  22963.     exec @retcode = dbo.sp_MSrepl_backup_complete
  22964.     if @retcode <> 0 or @@error <> 0
  22965.         return 0
  22966.  
  22967.     -- Support override of replication remove on attach and restore
  22968.     declare @instance sysname
  22969.     declare @regkey nvarchar(260)
  22970.     select @instance = convert(sysname, SERVERPROPERTY('InstanceName'))
  22971.     select @regkey = 'SOFTWARE\Microsoft\'
  22972.     -- default installation
  22973.     if @instance is null
  22974.         SELECT @regkey = @regkey + 'MSSQLServer\Replication' 
  22975.     else
  22976.         SELECT @regkey = @regkey + 'Microsoft SQL Server\' + @instance + '\Replication'
  22977.  
  22978.     SELECT @restoreoverride = 0 -- assume normal remove behavior
  22979.     SELECT @proc = 'master.dbo.xp_regread '
  22980.     EXECUTE @retcode = @proc    'HKEY_LOCAL_MACHINE', 
  22981.                                 @regkey,
  22982.                                 'RestoreOverride',
  22983.                                 @param = @restoreoverride OUTPUT,
  22984.                                 @no_output = 'no_output'
  22985.  
  22986.     if ( @@error = 0 ) and ( @retcode = 0 )
  22987.     begin
  22988.         -- ReplRestoreOverride = 1 = user elects to take no cleanup on restore or attach
  22989.         if ( isnull( @restoreoverride, 0 ) = 1 )
  22990.             return(0)
  22991.     end
  22992.     
  22993.         
  22994.     select @remove_repl = 0, @repl_installed = 1 
  22995.  
  22996.     select @db_curr = db_name() 
  22997.  
  22998.     -- check server has replication installed; if not, we cannot remove replication; this should be benign
  22999.     if not exists ( select * from master..MSreplication_options 
  23000.                         where optname = 'transactional' 
  23001.                            or optname = 'merge' )
  23002.         select @repl_installed = 0
  23003.  
  23004.     -- check restore to same server/db backed up
  23005.     if (( UPPER(@srv_orig) <> UPPER(@@SERVERNAME) ) or ( @db_orig <> @db_curr )) and 
  23006.         @keep_replication = 0
  23007.         select @remove_repl = 1
  23008.  
  23009.     -- even it is the same server/db, if it is enabled for neither merge nor tran, we will do rmove_repl.
  23010.     
  23011. --    if not exists (select * from master..sysdatabases where name = @db_curr collate database_default and category & @db_tranbit = @db_tranbit )
  23012. --        and not exists (select * from master..sysdatabases where name = @db_curr collate database_default and category & @db_mergbit = @db_mergbit )
  23013. --        select @remove_repl = 1        
  23014.     -- in order to comply with BOL on restoring subscriber databases, this code segment has to go. 
  23015.  
  23016.     -- upgrade repl schema to latest version if it is restore of earlier database version (e.g. SQL70 backup)
  23017.     if ( exists( select * from sysobjects where name = N'syspublications' ) -- we think this is a tran pub db
  23018.             and not exists ( select * from sysobjects where name = N'sysextendedarticlesview' ) )
  23019.         or
  23020.        ( exists( select * from sysobjects where name = N'sysmergepublications' ) -- we think this is a merge pub db
  23021.             and not exists ( select * from sysobjects where name = N'sysmergeextendedarticlesview' ) )
  23022.     begin
  23023.         exec dbo.sp_vupgrade_publisherdb @ver_old = 999, @ver_retention = 999 -- retention and old version not relevant on restore
  23024.  
  23025.         -- update subscription tables schema only -- skip any recompile of procs, views, etc. -- we will just drop them after restore
  23026.         exec dbo.sp_vupgrade_MSsubscription_properties
  23027.         exec dbo.sp_vupgrade_subscription_tables
  23028.         exec dbo.sp_vupgrade_mergetables @skip_procgen = 1
  23029.  
  23030.     end
  23031.  
  23032.     -- subscribing dbs are assumed ok
  23033.     -- distribution dbs are assumed ok
  23034.  
  23035.     -- publishing db check : transactional : requires coordinated restore of dist db - no way to check
  23036.     if ( 
  23037.             exists( select * from sysobjects where name = 'syspublications' )
  23038.             -- exists( select * from syspublications ) 
  23039.             and not exists( select * from master..sysdatabases 
  23040.                 where name = @db_curr collate database_default and category & @db_tranbit = @db_tranbit )
  23041.         )
  23042.     begin
  23043.         -- publications exist in db, but db on server is not published; 
  23044.         -- unpublish the db, ignoring distributor cleanup
  23045.  
  23046.         update master.dbo.sysdatabases set category = category | @db_tranbit where name = @db_curr collate database_default
  23047.         exec dbo.sp_MSpublishdb 'false', 1
  23048.         update master.dbo.sysdatabases set category = category & ~@db_tranbit where name = @db_curr collate database_default
  23049.  
  23050.         -- we've already brute force stripped replication from the db, 
  23051.         -- don't call sp_removedbreplication at proc exit
  23052.     end
  23053.  
  23054.     if ( @repl_installed = 1 ) and ( @remove_repl = 1 ) 
  23055.         exec dbo.sp_removedbreplication @db_curr
  23056.  
  23057.  
  23058. end
  23059. go
  23060.  
  23061. exec dbo.sp_MS_marksystemobject sp_restoredbreplication
  23062. go
  23063.  
  23064. --
  23065. -- Name: sp_MSget_publisher_rpc
  23066. --
  23067. -- Description: This proc is invoked on subscriber by synctran trigger
  23068. -- for retrieving publisher RPC connection information during  
  23069. -- immediate updating operation.
  23070. --
  23071. -- Parameter: Refer to the comments in the create procedure statement
  23072. --
  23073. -- Returns: 1 or 0   0 = success
  23074. --
  23075. -- Security: Public procedure - Internal security check. 
  23076. --
  23077. raiserror('Creating procedure sp_MSget_publisher_rpc', 0,1)
  23078. GO
  23079. CREATE PROCEDURE sp_MSget_publisher_rpc
  23080. (
  23081.     @trigger_id int
  23082.     ,@connect_string nvarchar(2000) output
  23083.     ,@owner sysname = null
  23084. )
  23085. AS
  23086. begin
  23087.     SET NOCOUNT ON
  23088.     declare @publisher sysname
  23089.                 ,@publisher_db sysname
  23090.                 ,@login sysname
  23091.                 ,@password nvarchar(524)
  23092.                 ,@security_mode int
  23093.                 ,@object_id int
  23094.                 ,@retcode int
  23095.  
  23096.     --
  23097.     -- Security check
  23098.     -- Make sure this proc is infact being called from the given object(trigger)
  23099.     -- 
  23100.     if trigger_nestlevel(@trigger_id) = 0
  23101.     begin
  23102.         raiserror(14126, 16, 4)
  23103.         return (1) -- current user does not have insert permission to underlying table
  23104.     end
  23105.     --
  23106.     -- Security check: the caller of this SP has to be one of the 
  23107.     -- predefined replication triggers defined in the db
  23108.     --
  23109.     if (@owner is null)
  23110.     begin
  23111.         if (@trigger_id not in (select object_id(object_name) 
  23112.                 from dbo.MSreplication_objects
  23113.                 where object_type = 'T'))
  23114.         begin
  23115.             raiserror(14126, 16, 4)
  23116.             return -1
  23117.         end
  23118.     end
  23119.     else
  23120.     begin
  23121.         if (@trigger_id not in (select object_id(quotename(@owner) + N'.' + quotename(object_name)) 
  23122.                 from dbo.MSreplication_objects
  23123.                 where object_type = 'T'))
  23124.         begin
  23125.             raiserror(14126, 16, 4)
  23126.             return -1
  23127.         end
  23128.     end
  23129.     --
  23130.     -- Get security from property table, if nothing find, the rpc will fail.
  23131.     --
  23132.     IF EXISTS (select * from dbo.sysobjects where name = 'MSsubscription_properties' and type = 'U')
  23133.     begin
  23134.         select @login = publisher_login,
  23135.                 @password = publisher_password,
  23136.                 @security_mode = publisher_security_mode,
  23137.                 @publisher = o.publisher,
  23138.                 @publisher_db = o.publisher_db
  23139.         from (dbo.MSsubscription_properties p join dbo.MSreplication_objects o
  23140.             on UPPER(p.publisher) = UPPER(o.publisher)
  23141.                 and p.publisher_db = o.publisher_db
  23142.                 and p.publication = o.publication)
  23143.         where o.object_name = object_name(@trigger_id) 
  23144.  
  23145.         exec @retcode = master.dbo.xp_repl_help_connect @password OUTPUT
  23146.         if @@error <> 0 OR @retcode <> 0
  23147.             return 1
  23148.     end
  23149.     else
  23150.     begin
  23151.         -- RPC security info invalid
  23152.         raiserror(21079, 16, -1)
  23153.         return(1)
  23154.     end
  23155.     --
  23156.     -- prepare the connect string now
  23157.     --
  23158.     if @security_mode = 2 -- 2 = use sysservers
  23159.     begin
  23160.         select @connect_string = null
  23161.     end
  23162.     else
  23163.     begin
  23164.         if @login is null
  23165.         begin
  23166.             -- RPC security info invalid
  23167.             raiserror(21079, 16, -1)
  23168.             return(1)
  23169.         end
  23170.  
  23171.         if @password is null
  23172.             select @password = N''
  23173.         -- Names containing space in connection string is automatically enabled.
  23174.         -- [] and ' are not recoginized by opendatasource
  23175.         -- Note ';' in names in connection string will mess things up.
  23176.         select @connect_string = 'SERVER=' + @publisher + ';UID=' + 
  23177.                 @login + ';PWD=' + @password + ';'
  23178.     end
  23179. end
  23180. GO
  23181. exec dbo.sp_MS_marksystemobject sp_MSget_publisher_rpc
  23182. go
  23183.  
  23184. raiserror('Creating procedure sp_link_publication', 0,1)
  23185. GO
  23186.  
  23187. CREATE PROCEDURE sp_link_publication (
  23188.     @publisher      sysname,            -- publishing server name
  23189.     @publisher_db   sysname,            -- publishing database name. If NULL then same as current db
  23190.     @publication    sysname,            -- publication name
  23191.     @security_mode  int,                -- 0 = standard; 2 = static linked server entry
  23192.     @login            sysname = NULL,
  23193.     @password        sysname = NULL,
  23194.     @distributor    sysname = NULL
  23195. )
  23196. AS
  23197. BEGIN
  23198.     set nocount on
  23199.     declare @retcode int
  23200.     declare @enc_password nvarchar(524)
  23201.     
  23202.     --  Security Check
  23203.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  23204.     IF @@ERROR <> 0 or @retcode <> 0
  23205.     RETURN(1)
  23206.  
  23207.     -- Parameter check: @security_mode
  23208.     if @security_mode <> 0 and @security_mode <> 2
  23209.     begin
  23210.         RAISERROR(21055, 16, -1, '@security_mode','sp_link_publication')
  23211.         RETURN (1)
  23212.     end
  23213.  
  23214.     if @security_mode = 2 and not exists (select * from master..sysservers where
  23215.         UPPER(srvname) = UPPER(@publisher) collate database_default)
  23216.     begin
  23217.         RAISERROR(20620, 16, -1, @publisher)
  23218.         RETURN (1)
  23219.     end
  23220.  
  23221.     IF @password = N''
  23222.         select @password = NULL
  23223.  
  23224.     /* 
  23225.     ** Check to see if MSsubscription_properties table exists.
  23226.     ** If not, create it.
  23227.     */
  23228.     exec @retcode = dbo.sp_MScreate_sub_tables
  23229.     IF @@ERROR <> 0 or @retcode <> 0
  23230.         return 1
  23231.  
  23232.     -- Encrypt the password
  23233.     set @enc_password = @password
  23234.     EXEC @retcode = master.dbo.xp_repl_encrypt @enc_password OUTPUT
  23235.     IF @@error <> 0 OR @retcode <> 0
  23236.         return 1
  23237.  
  23238.     IF NOT EXISTS (select * from MSsubscription_properties 
  23239.             where UPPER(publisher) = UPPER(@publisher)
  23240.                 and publisher_db =  @publisher_db
  23241.                 and publication = @publication) 
  23242.     BEGIN
  23243.         INSERT INTO MSsubscription_properties 
  23244.             (publisher, publisher_db, publication, publication_type, 
  23245.              publisher_login,publisher_password, publisher_security_mode, 
  23246.              distributor, distributor_login, distributor_password, 
  23247.              distributor_security_mode)
  23248.         values (@publisher, @publisher_db, @publication, 0,    @login, @enc_password, 
  23249.             @security_mode, @distributor, NULL, NULL, 1)
  23250.     END
  23251.     ELSE
  23252.     BEGIN
  23253.         update MSsubscription_properties set
  23254.             publisher_login = @login,
  23255.             publisher_password = @enc_password,
  23256.             publisher_security_mode = @security_mode,
  23257.             distributor = isnull(@distributor, distributor)
  23258.             where UPPER(publisher) = UPPER(@publisher)
  23259.                 and publisher_db =  @publisher_db
  23260.                 and publication = @publication
  23261.     END
  23262. END
  23263. go
  23264.  
  23265. exec dbo.sp_MS_marksystemobject sp_link_publication
  23266. go
  23267.  
  23268. -- This proc is invoked on subscriber.
  23269. -- internal routine - not granted to public
  23270. raiserror('Creating procedure sp_MSreset_queue', 0,1)
  23271. GO
  23272. CREATE PROCEDURE sp_MSreset_queue (
  23273.     @publisher      sysname,                    -- publishing server name
  23274.     @publisher_db   sysname,                    -- publishing database name. 
  23275.     @publication    sysname,                    -- publication name,
  23276.     @artid         int)
  23277. as
  23278. begin
  23279.     declare @subserver sysname
  23280.             ,@subdbname sysname
  23281.             ,@queue_id  sysname
  23282.             ,@update_mode int
  23283.             ,@retcode smallint
  23284.             ,@vbartid varbinary(20)
  23285.             ,@queue_server sysname
  23286.  
  23287.     set nocount on
  23288.  
  23289.     select     @subserver = @@servername, 
  23290.             @subdbname = db_name(),
  23291.             @update_mode = update_mode, 
  23292.             @queue_id = queue_id,
  23293.             @queue_server = queue_server
  23294.     from MSsubscription_agents
  23295.         where UPPER(publisher) = UPPER(@publisher)
  23296.             and publisher_db =  @publisher_db
  23297.             and publication = @publication
  23298.  
  23299.     if (@update_mode in (2,3))
  23300.     begin
  23301.         --
  23302.         -- MSMQ processing
  23303.         -- prefix the queue_id with queue server in direct format
  23304.         -- and then perform the queue reset
  23305.         --                        
  23306.         select @queue_id = N'DIRECT=OS:' + @queue_server + N'\PRIVATE$\' + @queue_id
  23307.         
  23308.         begin distributed tran
  23309.         exec @retcode = master.dbo.xp_resetqueue @queue_id, @subserver, 
  23310.                             @subdbname, @publication, @artid
  23311.         if (@retcode != 0 or @@error != 0)
  23312.         begin
  23313.             if (@@trancount > 0)
  23314.                 rollback tran
  23315.             return (1)    
  23316.         end
  23317.     end
  23318.     else if (@update_mode in (4,5))
  23319.     begin
  23320.         declare @tranid sysname
  23321.  
  23322.         begin tran
  23323.         --
  23324.         -- process MSreplication_queue
  23325.         --
  23326.         select @retcode = 0
  23327.         if (exists (select * from sysobjects 
  23328.             where name = 'MSreplication_queue'))
  23329.         begin
  23330.             --
  23331.             -- Strictly speaking we do no need
  23332.             -- to delete but, makes it easy for
  23333.             -- the queue reader agent
  23334.             -- Do not delete any reset messages
  23335.             --
  23336.             delete dbo.MSreplication_queue
  23337.                 where publisher = UPPER(@publisher)
  23338.                 and publisher_db =  @publisher_db
  23339.                 and publication = @publication
  23340.                 and tranid not like N'sub-reset%'
  23341.         end
  23342.         else
  23343.         begin
  23344.             --
  23345.             -- first queue subscription is being initialized
  23346.             -- create queue if necessary
  23347.             --
  23348.             exec @retcode = sp_MScreate_sub_tables
  23349.                 @tran_sub_table = 0,
  23350.                 @property_table = 0,
  23351.                 @sqlqueue_table = 1
  23352.         end
  23353.         if (@retcode != 0 or @@error != 0)
  23354.         begin
  23355.             if (@@trancount > 0)
  23356.                 rollback tran
  23357.             return (1)    
  23358.         end
  23359.         --
  23360.         -- process MSrepl_queuedtraninfo
  23361.         --
  23362.         if (exists (select * from sysobjects 
  23363.             where name = 'MSrepl_queuedtraninfo'))
  23364.         begin
  23365.             --
  23366.             -- Strictly speaking we do no need
  23367.             -- to delete but, makes it easy for
  23368.             -- the queue reader agent
  23369.             -- Do not delete any reset messages
  23370.             --
  23371.             delete dbo.MSrepl_queuedtraninfo
  23372.                 where publisher = UPPER(@publisher)
  23373.                 and publisher_db =  @publisher_db
  23374.                 and publication = @publication
  23375.                 and tranid not like N'sub-reset%'
  23376.         end
  23377.         else
  23378.         begin
  23379.             --
  23380.             -- first queue subscription is being initialized
  23381.             -- create the traninfo if necessary
  23382.             --
  23383.             exec @retcode = sp_MScreate_sub_tables
  23384.                 @tran_sub_table = 0,
  23385.                 @property_table = 0,
  23386.                 @sqlqueue_table = 1
  23387.         end
  23388.         if (@retcode != 0 or @@error != 0)
  23389.         begin
  23390.             if (@@trancount > 0)
  23391.                 rollback tran
  23392.             return (1)    
  23393.         end
  23394.         --
  23395.         -- for subscription reinitialization we
  23396.         -- need to insert a RESYNC command message
  23397.         --
  23398.         select @vbartid = cast(@artid as varbinary(20))
  23399.                 ,@tranid = N'sub-reset-' + cast(NEWID() as sysname)
  23400.         insert into dbo.MSreplication_queue (publisher, publisher_db,
  23401.             publication,tranid, commandtype, data, datalen)
  23402.         values (UPPER(@publisher), @publisher_db, 
  23403.             @publication, @tranid, 2, @vbartid, datalength(@vbartid))
  23404.         if ((@@error != 0) or (@retcode != 0))
  23405.         begin
  23406.             if (@@trancount > 0)
  23407.                 rollback tran
  23408.             return (1)    
  23409.         end
  23410.         --
  23411.         -- add an entry in MSrepl_queuedtraninfo
  23412.         --
  23413.         insert into dbo.MSrepl_queuedtraninfo (publisher,publisher_db,publication,tranid,maxorderkey,commandcount)
  23414.         values (UPPER(@publisher),@publisher_db,@publication,@tranid,@@identity,1)
  23415.     end
  23416.  
  23417.     commit tran
  23418.     return 0
  23419. end            
  23420. GO
  23421. exec dbo.sp_MS_marksystemobject sp_MSreset_queue
  23422. go
  23423.  
  23424. --
  23425. -- Name: sp_MSreset_queued_reinit
  23426. --
  23427. -- Description: This proc is invoked on publisher, for resetting
  23428. -- the queued_reinit flag for a given subscription
  23429. --
  23430. -- Parameter: Refer to the comments in the create procedure statement
  23431. --
  23432. -- Returns: 1 or 0   0 = success
  23433. --
  23434. -- Security: Public procedure - does PAL security check. 
  23435. --
  23436. raiserror('Creating procedure sp_MSreset_queued_reinit', 0,1)
  23437. GO
  23438. create procedure sp_MSreset_queued_reinit (
  23439.     @subscriber      sysname,                    -- subscriber server name
  23440.     @subscriber_db   sysname,                    -- subscribing database name. 
  23441.     @artid    int)                                   -- article id
  23442. as
  23443. begin
  23444.     set nocount on
  23445.     declare @srvid int
  23446.         ,@retcode int
  23447.         ,@publication sysname
  23448.     --
  23449.     -- PAL security check
  23450.     -- Get publication name using artid
  23451.     --
  23452.     select @publication = p.name
  23453.     from syspublications p join sysarticles a on p.pubid = a.pubid
  23454.     where a.artid = @artid
  23455.     if (@publication is null)
  23456.     begin
  23457.         return 1
  23458.     end
  23459.     exec @retcode = dbo.sp_MSreplcheck_pull @publication = @publication
  23460.     if @@error <> 0 or @retcode <> 0
  23461.     begin
  23462.         return (1)
  23463.     end
  23464.     select @srvid = srvid from master.dbo.sysservers where UPPER(srvname) = UPPER(@subscriber) collate database_default
  23465.     --
  23466.     -- set the reinit flag
  23467.     --
  23468.     update dbo.syssubscriptions
  23469.     set queued_reinit = 0
  23470.     where 
  23471.         artid = @artid 
  23472.         and srvid = @srvid
  23473.         and dest_db = @subscriber_db
  23474.     if (@@error != 0)
  23475.         return 1
  23476.  
  23477.     -- all done
  23478.     return 0
  23479. end            
  23480. GO
  23481. exec dbo.sp_MS_marksystemobject sp_MSreset_queued_reinit
  23482. go
  23483. grant execute on dbo.sp_MSreset_queued_reinit to public
  23484. go
  23485.  
  23486. raiserror('Creating procedure sp_MSinit_subscription_agent', 0,1)
  23487. GO
  23488.  
  23489. -- This proc is called by distribution agent.
  23490. CREATE PROCEDURE sp_MSinit_subscription_agent
  23491.     @publisher      sysname,                    -- publishing server name
  23492.     @publisher_db   sysname,                    -- publishing database name. If NULL then same as current db
  23493.     @publication    sysname,                    -- publication name,
  23494.     @subscription_type int
  23495. AS
  23496.     set nocount on
  23497.     declare @retcode int
  23498.     declare @login_time datetime
  23499.  
  23500.     --  Security Check
  23501.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  23502.     IF @@ERROR <> 0 or @retcode <> 0
  23503.     RETURN(1)
  23504.  
  23505.     -- For non independent agent publications
  23506.     if @publication is null or @publication = ''
  23507.         set @publication = 'ALL'
  23508.     
  23509.       select @login_time = login_time from master..sysprocesses where spid = @@spid
  23510.  
  23511.     if not exists (select * from MSsubscription_agents where
  23512.             UPPER(publisher) = UPPER(@publisher)
  23513.             and publisher_db =  @publisher_db
  23514.             and publication = @publication
  23515.             and subscription_type = @subscription_type)
  23516.     begin
  23517.         INSERT INTO MSsubscription_agents
  23518.             (publisher, publisher_db, publication, subscription_type,
  23519.              queue_id, update_mode, failover_mode, spid, login_time )
  23520.         values (@publisher, @publisher_db, @publication, @subscription_type, 
  23521.             null, 1, 0, @@spid, @login_time)
  23522.     end
  23523.     else
  23524.     begin
  23525.         -- It is possible that 2 instance of the distribution agent do this update at 
  23526.         -- the same time. One will fail later at the instance check at the distributor
  23527.         -- side. We no longer use the spid and login_time column anywhere else. 
  23528.         update MSsubscription_agents set      
  23529.             spid = @@spid,
  23530.             login_time = @login_time
  23531.             where UPPER(publisher) = UPPER(@publisher)
  23532.                 and publisher_db =  @publisher_db
  23533.                 and publication = @publication
  23534.                 and subscription_type = @subscription_type
  23535.     end
  23536. go
  23537.  
  23538. exec dbo.sp_MS_marksystemobject sp_MSinit_subscription_agent
  23539. go
  23540. grant execute on dbo.sp_MSinit_subscription_agent to public
  23541. go
  23542.  
  23543. raiserror('Creating procedure sp_MSupdatelastsyncinfo', 0,1)
  23544. GO
  23545.  
  23546. -- This proc is called by distribution agent.
  23547. CREATE PROCEDURE sp_MSupdatelastsyncinfo
  23548.     @publisher      sysname,                    -- publishing server name
  23549.     @publisher_db   sysname,                    -- publishing database name. If NULL then same as current db
  23550.     @publication    sysname,                    -- publication name,
  23551.     @subscription_type int,
  23552.     @last_sync_status     int,
  23553.     @last_sync_summary     sysname
  23554. AS
  23555.     set nocount on
  23556.     declare @retcode int
  23557.  
  23558.     --  Security Check
  23559.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  23560.     IF @@ERROR <> 0 or @retcode <> 0
  23561.         RETURN(1)
  23562.     
  23563.     if object_id('dbo.MSsubscription_agents') is null
  23564.         return(1)
  23565.  
  23566.     -- For non independent agent publications
  23567.     if @publication is null or @publication = ''
  23568.         set @publication = 'ALL'
  23569.  
  23570.     if not exists (select * from MSsubscription_agents where
  23571.             UPPER(publisher) = UPPER(@publisher)
  23572.             and publisher_db =  @publisher_db
  23573.             and publication = @publication
  23574.             and subscription_type = @subscription_type)
  23575.     begin
  23576.         exec dbo.sp_MSinit_subscription_agent
  23577.             @publisher,
  23578.             @publisher_db,
  23579.             @publication,
  23580.             @subscription_type
  23581.     end
  23582.  
  23583.     update MSsubscription_agents set     
  23584.         last_sync_time = getdate(), 
  23585.         last_sync_status = @last_sync_status, 
  23586.         last_sync_summary = @last_sync_summary
  23587.         where UPPER(publisher) = UPPER(@publisher)
  23588.             and publisher_db =  @publisher_db
  23589.             and publication = @publication
  23590.             and subscription_type = @subscription_type
  23591.  
  23592.     update MSreplication_subscriptions set
  23593.         time = convert(smalldatetime, getdate()) 
  23594.     WHERE UPPER(publisher) = UPPER(@publisher) AND
  23595.         publisher_db  = @publisher_db AND
  23596.         ((@publication = N'ALL' and independent_agent = 0) or 
  23597.         @publication = publication) and
  23598.         subscription_type = @subscription_type
  23599. go
  23600.  
  23601. exec dbo.sp_MS_marksystemobject sp_MSupdatelastsyncinfo
  23602. go
  23603. grant execute on dbo.sp_MSupdatelastsyncinfo to public
  23604. go
  23605.  
  23606.  
  23607. raiserror('Creating procedure sp_MSget_attach_state', 0,1)
  23608. GO
  23609.  
  23610. -- This proc is called by distribution agent.
  23611. CREATE PROCEDURE sp_MSget_attach_state
  23612.     @publisher      sysname,                    -- publishing server name
  23613.     @publisher_db   sysname,                    -- publishing database name. If NULL then same as current db
  23614.     @publication    sysname,                    -- publication name,
  23615.     @subscription_type int
  23616. AS
  23617.     set nocount on
  23618.     declare @retcode int
  23619.  
  23620.     --  Security Check
  23621.     --  We only run on subscriber so we only need sysadmin and dbo
  23622.     exec @retcode = dbo.sp_MSreplcheck_publish
  23623.     if @@error <> 0 or @retcode <> 0
  23624.     begin
  23625.         return (1)
  23626.     end
  23627.  
  23628.     
  23629.     -- For non independent agent publications
  23630.     if @publication is null or @publication = ''
  23631.         set @publication = 'ALL'
  23632.  
  23633.     select attach_state, attach_version from MSsubscription_agents
  23634.         where UPPER(publisher) = UPPER(@publisher)
  23635.             and publisher_db =  @publisher_db
  23636.             and publication = @publication
  23637.             and subscription_type = @subscription_type
  23638. go
  23639.  
  23640. exec dbo.sp_MS_marksystemobject sp_MSget_attach_state
  23641. go
  23642. grant execute on dbo.sp_MSget_attach_state to public
  23643. go
  23644.  
  23645.  
  23646. raiserror('Creating procedure sp_MSreset_attach_state', 0,1)
  23647. GO
  23648.  
  23649. -- This proc is called by distribution agent.
  23650. CREATE PROCEDURE sp_MSreset_attach_state (
  23651.     @publisher      sysname,                    -- publishing server name
  23652.     @publisher_db   sysname,                    -- publishing database name. If NULL then same as current db
  23653.     @publication    sysname,                    -- publication name,
  23654.     @subscription_type int
  23655.     )
  23656. AS
  23657. BEGIN
  23658.     set nocount on
  23659.     declare @retcode int
  23660.  
  23661.     --  Security Check
  23662.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  23663.     IF @@ERROR <> 0 or @retcode <> 0
  23664.     RETURN(1)
  23665.     
  23666.  
  23667.     -- For non independent agent publications
  23668.     if @publication is null or @publication = ''
  23669.         select @publication = 'ALL'
  23670.  
  23671.     --
  23672.     -- For Queued updating subscriptions, (re)initialize
  23673.     -- the queue
  23674.     --
  23675.     if exists (select * from dbo.MSsubscription_agents 
  23676.         where UPPER(publisher) = UPPER(@publisher)
  23677.             and publisher_db =  @publisher_db
  23678.             and publication = @publication
  23679.             and subscription_type = @subscription_type
  23680.             and update_mode in (2,3,4,5))
  23681.     begin
  23682.         declare @artid int
  23683.  
  23684.         --
  23685.         -- for each article in this subscription
  23686.         --
  23687.         declare #hc_article CURSOR LOCAL FORWARD_ONLY for 
  23688.             select artid 
  23689.             from dbo.MSsubscription_articles as art join dbo.MSsubscription_agents as agent
  23690.                 on art.agent_id = agent.id
  23691.             where UPPER(agent.publisher) = UPPER(@publisher)
  23692.                 and agent.publisher_db =  @publisher_db
  23693.                 and agent.publication = @publication
  23694.                 and agent.subscription_type = @subscription_type
  23695.  
  23696.         open #hc_article
  23697.         fetch #hc_article into @artid
  23698.         while (@@fetch_status = 0)
  23699.         begin        
  23700.             --
  23701.             -- we cannot have an NULL article id
  23702.             --
  23703.             if (@artid IS NULL)
  23704.             begin
  23705.                 raiserror('sp_MSreset_attach_state(debug) - queued article id cannot be NULL', 16, 1)
  23706.                 return (1)
  23707.             end
  23708.             --
  23709.             -- reset the queue
  23710.             --
  23711.             exec @retcode = dbo.sp_MSreset_queue @publisher, @publisher_db, @publication, @artid
  23712.             IF (@retcode != 0 or @@ERROR != 0)
  23713.             begin
  23714.                 raiserror('sp_MSreset_attach_state(debug) - sp_MSreset_queue failed', 16, 2)
  23715.                 return (1)
  23716.             end
  23717.             --
  23718.             -- fetch next article
  23719.             --
  23720.             fetch #hc_article into @artid
  23721.         end
  23722.         close #hc_article
  23723.         deallocate #hc_article
  23724.     end
  23725.  
  23726.     update MSsubscription_agents set attach_state = 0
  23727.         where UPPER(publisher) = UPPER(@publisher)
  23728.             and publisher_db =  @publisher_db
  23729.             and publication = @publication
  23730.             and subscription_type = @subscription_type
  23731. END
  23732. go
  23733.  
  23734. exec dbo.sp_MS_marksystemobject sp_MSreset_attach_state
  23735. go
  23736. grant execute on dbo.sp_MSreset_attach_state to public
  23737. go
  23738.  
  23739. --
  23740. -- Name: sp_MSset_subscription_properties
  23741. --
  23742. -- Description: This procedure is called by distribution agent to set the 
  23743. -- subscription metadata during subscription initialization. Invoked on subscribing
  23744. -- database on subscriber.
  23745. --
  23746. -- Parameter: Refer to the comments in the create procedure statement
  23747. --
  23748. -- Returns: 1 or 0   0 = success
  23749. --
  23750. -- Security: Public procedure - internal security check. 
  23751. --
  23752. raiserror('Creating procedure sp_MSset_subscription_properties', 0,1)
  23753. GO
  23754. CREATE PROCEDURE sp_MSset_subscription_properties (
  23755.     @publisher      sysname,                    -- publishing server name
  23756.     @publisher_db   sysname,                    -- publishing database name. If NULL then same as current db
  23757.     @publication    sysname,                    -- publication name,
  23758.     @subscription_type int,
  23759.     @allow_subscription_copy bit,
  23760.     @queue_id sysname,
  23761.     @update_mode int,
  23762.     @attach_version binary(16),
  23763.     @queue_server sysname = NULL
  23764. )
  23765. AS
  23766. BEGIN
  23767.     set nocount on
  23768.     declare @retcode int
  23769.  
  23770.     --  Security Check
  23771.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  23772.     IF @@ERROR <> 0 or @retcode <> 0
  23773.         RETURN(1)
  23774.  
  23775.     -- For non independent agent publications
  23776.     if @publication is null or @publication = ''
  23777.         set @publication = 'ALL'
  23778.  
  23779.     if @queue_server = N''
  23780.         select @queue_server = NULL
  23781.  
  23782.     if @queue_id = N''
  23783.         select @queue_id = NULL
  23784.     --
  23785.     -- Update metadata in MSsubscription_agents
  23786.     --
  23787.     update dbo.MSsubscription_agents set      
  23788.         allow_subscription_copy = @allow_subscription_copy,
  23789.         update_mode = @update_mode,
  23790.         queue_id = @queue_id,
  23791.         queue_server = @queue_server,
  23792.         attach_version = @attach_version
  23793.     where UPPER(publisher) = UPPER(@publisher)
  23794.         and publisher_db =  @publisher_db
  23795.         and publication = @publication
  23796.         and subscription_type = @subscription_type
  23797.     --
  23798.     -- for queued pull subscriptions 
  23799.     -- update column update_mode in MSreplication_subscriptions
  23800.     -- as we never know the right update_mode until initialization
  23801.     --
  23802.     if ((@subscription_type = 1) and (@queue_id IS NOT NULL) and
  23803.     exists (select * from MSreplication_subscriptions 
  23804.         WHERE UPPER(publisher) = UPPER(@publisher) AND
  23805.             publisher_db  = @publisher_db AND
  23806.             publication = @publication AND
  23807.             subscription_type = @subscription_type))
  23808.     begin
  23809.         update MSreplication_subscriptions 
  23810.         set update_mode = @update_mode
  23811.         WHERE UPPER(publisher) = UPPER(@publisher) AND
  23812.             publisher_db  = @publisher_db AND
  23813.             publication = @publication AND
  23814.             subscription_type = @subscription_type
  23815.     end
  23816. END
  23817. go
  23818.  
  23819. exec dbo.sp_MS_marksystemobject sp_MSset_subscription_properties
  23820. go
  23821. grant execute on dbo.sp_MSset_subscription_properties to public
  23822. go
  23823.  
  23824. --
  23825. -- Name: sp_MSset_sub_guid
  23826. --
  23827. -- Description: This procedure is called by distribution agent to set the 
  23828. -- subscription metadata during subscription attach. Invoked on subscribing
  23829. -- database on subscriber.
  23830. --
  23831. -- Parameter: Refer to the comments in the create procedure statement
  23832. --
  23833. -- Returns: 1 or 0   0 = success
  23834. --
  23835. -- Security: Public procedure - internal security check. 
  23836. --
  23837. raiserror('Creating procedure sp_MSset_sub_guid', 0,1)
  23838. GO
  23839. CREATE PROCEDURE sp_MSset_sub_guid (
  23840.     @publisher      sysname,                    -- publishing server name
  23841.     @publisher_db   sysname,                    -- publishing database name. If NULL then same as current db
  23842.     @publication    sysname,                    -- publication name,
  23843.     @subscription_type int,
  23844.     @subscription_guid binary(16),
  23845.     @queue_id        sysname,
  23846.     @queue_server    sysname = NULL
  23847. )
  23848. AS
  23849. BEGIN
  23850.     set nocount on
  23851.     declare @retcode int
  23852.                 ,@independent_agent bit
  23853.                 ,@subqueue_id sysname
  23854.  
  23855.     --  Security Check
  23856.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  23857.     IF @@ERROR <> 0 or @retcode <> 0
  23858.         RETURN(1)
  23859.  
  23860.     -- For non independent agent publications
  23861.     if @publication is null or @publication = ''
  23862.     begin
  23863.         select @publication = 'ALL'
  23864.                 ,@independent_agent = 0
  23865.     end
  23866.     else
  23867.         select @independent_agent = 1
  23868.  
  23869.     if @queue_id = N''
  23870.         select @queue_id = NULL
  23871.  
  23872.     if @queue_server = N''
  23873.         select @queue_server = NULL
  23874.     --
  23875.     -- Special processing when we are dealing with pull SQL queue updating subscription
  23876.     --
  23877.     if ((@subscription_type = 1) and substring(@queue_id, 1, 10) = N'mssqlqueue')
  23878.     begin
  23879.         --
  23880.         -- For SQL Queue case - Check the current queue_id on the table
  23881.         --
  23882.         select @subqueue_id = queue_id
  23883.         from dbo.MSsubscription_agents
  23884.         where UPPER(publisher) = UPPER(@publisher)
  23885.             and publisher_db =  @publisher_db
  23886.             and publication = @publication
  23887.             and subscription_type = @subscription_type
  23888.         if (@subqueue_id is not NULL and substring(@subqueue_id, 1, 10) = N'mssqlqueue')
  23889.         begin
  23890.             --
  23891.             -- Use the local Queue ID on subscriber as this contains the queue version. 
  23892.             -- We are attaching an initialized subscription and do not want to change the 
  23893.             -- queue version stored in queue_id for SQL Queues. The value passed by Distribution
  23894.             -- Agent is from the distributor metadata and does not contain the queue version information.
  23895.             -- This is specific to SQL Queues only.
  23896.             --
  23897.             select @queue_id = @subqueue_id
  23898.         end
  23899.     end
  23900.     --
  23901.     -- Update metadata in MSsubscription_agents
  23902.     --
  23903.     update MSsubscription_agents set      
  23904.         queue_id = @queue_id
  23905.         ,queue_server = @queue_server
  23906.     where UPPER(publisher) = UPPER(@publisher)
  23907.     and publisher_db =  @publisher_db
  23908.     and publication = @publication
  23909.     and subscription_type = @subscription_type
  23910.  
  23911.     update MSreplication_subscriptions set      
  23912.         [time] = getdate(),
  23913.         subscription_guid = @subscription_guid
  23914.     where UPPER(publisher) = UPPER(@publisher)
  23915.         and publisher_db =  @publisher_db
  23916.         and (@independent_agent = 0 or publication = @publication)
  23917.         and subscription_type = @subscription_type
  23918.         and independent_agent = @independent_agent
  23919. END
  23920. go
  23921. exec dbo.sp_MS_marksystemobject sp_MSset_sub_guid
  23922. go
  23923. grant execute on dbo.sp_MSset_sub_guid to public
  23924. go
  23925.  
  23926. --
  23927. -- sp_populateqtraninfo
  23928. --
  23929. -- Owner: KaushikC
  23930. --
  23931. -- Description: this stored procedure populates table 
  23932. -- MSrepl_queuedtraninfo based on the existing data
  23933. -- in MSreplication_queue. It is used during the 
  23934. -- upgrade process when MSrepl_queuedtraninfo is 
  23935. -- created. Executed on subscriber database.
  23936. --
  23937. -- Parameters:  
  23938. --        as defined in the create proc statement
  23939. --
  23940. -- Results:
  23941. --    None
  23942. --
  23943. -- Returns:
  23944. --         0 if success
  23945. --        1 if failure
  23946. --
  23947. -- Security: internal helper procedure - not granted to public 
  23948. --
  23949. raiserror('Creating procedure sp_populateqtraninfo', 0,1)
  23950. GO
  23951. CREATE PROCEDURE sp_populateqtraninfo 
  23952. as
  23953. begin
  23954.     --
  23955.     -- initiate local transaction
  23956.     --
  23957.     begin tran sp_populateqtraninfo
  23958.     save tran sp_populateqtraninfo
  23959.     --
  23960.     -- see if we need to populate
  23961.     --
  23962.     if EXISTS (SELECT * FROM dbo.MSreplication_queue)
  23963.     begin
  23964.         --
  23965.         -- There is data in queue
  23966.         -- Populate MSrepl_queuedtraninfo based on what is there
  23967.         --
  23968.         declare @publisher sysname
  23969.                 ,@publisherdb sysname
  23970.                 ,@publication sysname
  23971.                 ,@tranid sysname
  23972.                 ,@orderkey bigint
  23973.                 ,@commandcount bigint
  23974.                 
  23975.         declare #htctranseq cursor local for
  23976.             select publisher, publisher_db, publication, tranid, orderkey
  23977.             from dbo.MSreplication_queue with (READPAST) 
  23978.             order by orderkey asc
  23979.         open #htctranseq
  23980.         fetch #htctranseq into @publisher, @publisherdb, @publication, @tranid, @orderkey
  23981.         IF @@ERROR <> 0
  23982.             goto cleanup
  23983.         while (@@fetch_status != -1)
  23984.         begin
  23985.             --
  23986.             -- update/insert entry in MSrepl_queuedtraninfo for this transaction
  23987.             --                
  23988.             if exists (select *
  23989.                 from dbo.MSrepl_queuedtraninfo
  23990.                 where publisher = UPPER(@publisher) 
  23991.                     and publisher_db = @publisherdb 
  23992.                     and publication = @publication
  23993.                     and tranid = @tranid)
  23994.             begin
  23995.                 --
  23996.                 -- row for this transaction exists - update it
  23997.                 --
  23998.                 update dbo.MSrepl_queuedtraninfo
  23999.                 set maxorderkey = @orderkey
  24000.                     ,commandcount = commandcount + 1
  24001.                 where publisher = UPPER(@publisher) 
  24002.                     and publisher_db = @publisherdb 
  24003.                     and publication = @publication
  24004.                     and tranid = @tranid
  24005.             end
  24006.             else
  24007.             begin
  24008.                 --
  24009.                 -- row for this transaction does not exist - insert it
  24010.                 --
  24011.                 insert into dbo.MSrepl_queuedtraninfo (publisher,publisher_db,publication,tranid,maxorderkey,commandcount)
  24012.                 values (UPPER(@publisher),@publisherdb,@publication,@tranid,@orderkey,1)
  24013.             end
  24014.             IF @@ERROR <> 0
  24015.                 goto cleanup
  24016.             --
  24017.             -- get the next row
  24018.             --
  24019.             fetch #htctranseq into @publisher, @publisherdb, @publication, @tranid, @orderkey
  24020.         end
  24021.         close #htctranseq
  24022.         deallocate #htctranseq
  24023.     end
  24024.     --
  24025.     -- commit local transaction
  24026.     --
  24027.     commit tran sp_populateqtraninfo
  24028.     --
  24029.     -- all done
  24030.     --
  24031.     return 0
  24032.  
  24033. cleanup:
  24034.     --
  24035.     -- error cleanup
  24036.     -- rollback local tran
  24037.     --
  24038.     rollback tran sp_populateqtraninfo
  24039.     commit tran
  24040.     return 1
  24041. end
  24042. go
  24043. exec dbo.sp_MS_marksystemobject sp_populateqtraninfo
  24044. go
  24045.  
  24046. raiserror('Creating procedure sp_MScreate_sub_tables', 0,1)
  24047. GO
  24048.  
  24049. CREATE PROCEDURE sp_MScreate_sub_tables (
  24050. @tran_sub_table bit = 0,
  24051. @property_table bit = 1,
  24052. @sqlqueue_table bit = 0
  24053. )
  24054. as
  24055. BEGIN
  24056.     set nocount on
  24057.     declare @retcode int
  24058.  
  24059.     IF @tran_sub_table = 1 and
  24060.         (NOT EXISTS (SELECT * FROM sysobjects WHERE 
  24061.         type = 'U' AND name = 'MSreplication_subscriptions')) 
  24062.     BEGIN
  24063.         CREATE TABLE dbo.MSreplication_subscriptions
  24064.         (
  24065.         publisher sysname NOT NULL,
  24066.         publisher_db sysname NOT NULL, 
  24067.         publication sysname NULL, 
  24068.         independent_agent bit NOT NULL,
  24069.         subscription_type int NOT NULL,
  24070.         distribution_agent sysname NULL, 
  24071.         time smalldatetime NOT NULL,
  24072.         description nvarchar(255) NULL,
  24073.         transaction_timestamp varbinary(16) NOT NULL,
  24074.         -- SyncTran
  24075.         update_mode tinyint NOT NULL,
  24076.         agent_id binary(16) NULL,
  24077.         subscription_guid binary(16) NULL,
  24078.         subid binary(16) NULL,
  24079.         immediate_sync bit NOT NULL default 1 -- sync_mode with a default of 1
  24080.         )
  24081.         IF @@ERROR <> 0
  24082.             GOTO UNDO
  24083.         CREATE UNIQUE CLUSTERED INDEX uc1MSReplication_subscriptions ON
  24084.                 MSreplication_subscriptions(publication, publisher_db, publisher, subscription_type)
  24085.         IF @@ERROR <> 0
  24086.             GOTO UNDO
  24087.  
  24088.         EXEC dbo.sp_MS_marksystemobject 'MSreplication_subscriptions'
  24089.          IF @@ERROR <> 0
  24090.             GOTO UNDO
  24091.     END    
  24092.  
  24093.  
  24094.     IF @tran_sub_table = 1
  24095.     BEGIN
  24096.         IF NOT EXISTS (SELECT * FROM sysobjects WHERE 
  24097.             type = 'U' AND name = 'MSsubscription_agents') 
  24098.         BEGIN
  24099.             CREATE TABLE dbo.MSsubscription_agents
  24100.             (
  24101.             id int identity,
  24102.             publisher sysname NOT NULL,
  24103.             publisher_db sysname NOT NULL, 
  24104.             publication sysname NOT NULL, 
  24105.             subscription_type int NOT NULL,
  24106.             queue_id sysname NULL,
  24107.             update_mode tinyint default 0 not null, -- 0 = read only, 1 = sync/immediate, 2 = queued, 3 = failover, 4 = sqlqueued, 5 = sqlqueued failover
  24108.             failover_mode bit default 0 not null, -- 0 - sync/immediate, 1 = queued
  24109.             spid int NOT NULL,
  24110.             login_time datetime NOT NULL,
  24111.             allow_subscription_copy bit default 0 not null,
  24112.             attach_state int default 0 not null,    -- 0: not attached 1 attached but not processed 2 attached and processed.
  24113.             attach_version binary(16) default newid() not null,
  24114.             last_sync_status int NULL, -- allow null for upgrade
  24115.             last_sync_summary sysname NULL, -- allow null for upgrade
  24116.             last_sync_time datetime NULL, -- allow null for upgrade
  24117.             queue_server sysname NULL -- only used for MSMQ based updating subscribers
  24118.             )
  24119.             IF @@ERROR <> 0
  24120.                 GOTO UNDO
  24121.  
  24122.             CREATE unique CLUSTERED INDEX ucMSsubscription_agents ON dbo.MSsubscription_agents
  24123.                 (publication, publisher_db, publisher, subscription_type)
  24124.  
  24125.             CREATE INDEX ucMSsubscription_agents_id ON dbo.MSsubscription_agents
  24126.                 (id)
  24127.  
  24128.             EXEC dbo.sp_MS_marksystemobject 'MSsubscription_agents'
  24129.             IF @@ERROR <> 0
  24130.                 GOTO UNDO
  24131.  
  24132.             grant select on dbo.MSsubscription_agents to public
  24133.             IF @@ERROR <> 0
  24134.                 GOTO UNDO
  24135.         END
  24136.         ELSE
  24137.         BEGIN
  24138.             --
  24139.             -- table exists - add new columns
  24140.             --
  24141.             if not exists (select * from dbo.syscolumns where 
  24142.                 id = object_id('MSsubscription_agents') and
  24143.                 name = 'queue_server')
  24144.             begin
  24145.                 alter table dbo.MSsubscription_agents add queue_server sysname NULL
  24146.                 exec dbo.sp_MSupdate_mqserver_subdb
  24147.             end
  24148.         END
  24149.      END
  24150.  
  24151.     IF @property_table = 1 and
  24152.         NOT EXISTS (SELECT * FROM sysobjects WHERE 
  24153.         type = 'U' AND
  24154.         name = 'MSsubscription_properties')
  24155.     BEGIN
  24156.         BEGIN TRAN
  24157.  
  24158.         CREATE TABLE dbo.MSsubscription_properties
  24159.         (
  24160.         publisher                        sysname        NOT NULL,
  24161.         publisher_db                    sysname        NOT NULL,
  24162.         publication                        sysname        NOT NULL,
  24163.         publication_type                int            NOT NULL,
  24164.         publisher_login                    sysname        NULL,
  24165.         publisher_password                nvarchar(524) NULL,
  24166.         publisher_security_mode            int            NOT NULL,
  24167.         distributor                        sysname        NULL,
  24168.         distributor_login                sysname        NULL,
  24169.         distributor_password            nvarchar(524) NULL,
  24170.         distributor_security_mode        int            NOT NULL,
  24171.         ftp_address                        sysname        NULL,
  24172.         ftp_port                        int            NULL,
  24173.         ftp_login                        sysname        NULL,
  24174.         ftp_password                    nvarchar(524) NULL,
  24175.         alt_snapshot_folder             nvarchar(255) NULL,
  24176.         working_directory               nvarchar(255) NULL,
  24177.         use_ftp                            bit default 0 NOT NULL,
  24178.         dts_package_name                sysname NULL,
  24179.         dts_package_password            nvarchar(524) NULL,
  24180.         -- default to be at the subscriber
  24181.         dts_package_location            int    default 1 NOT NULL,
  24182.         enabled_for_syncmgr                bit default 0 NOT NULL,
  24183.         offload_agent                   bit default 0 NOT NULL,
  24184.         offload_server                  sysname     NULL,
  24185.         dynamic_snapshot_location       nvarchar(255) NULL
  24186.         )
  24187.         IF @@ERROR <> 0
  24188.             GOTO UNDO
  24189.  
  24190.         CREATE UNIQUE CLUSTERED INDEX uc1MSsubscription_properties ON
  24191.                 MSsubscription_properties(publication, publisher_db, publisher)
  24192.         IF @@ERROR <> 0
  24193.             GOTO UNDO
  24194.         
  24195.         EXEC @retcode = dbo.sp_MS_marksystemobject 'MSsubscription_properties'
  24196.         if @retcode <> 0 or @@error <> 0
  24197.             GOTO UNDO
  24198.  
  24199.         COMMIT TRAN
  24200.     END
  24201.  
  24202.     IF @sqlqueue_table = 1
  24203.     BEGIN
  24204.         declare @folddata bit
  24205.  
  24206.         BEGIN TRAN    
  24207.         if EXISTS (SELECT * FROM dbo.sysobjects WHERE 
  24208.                 type = 'U' AND name = 'MSreplication_queue')
  24209.         BEGIN
  24210.             --
  24211.             -- table exists - check if we need to add columns
  24212.             --
  24213.             if not exists (select * from dbo.syscolumns where 
  24214.                     id = object_id('MSreplication_queue') and
  24215.                     name = 'cmdstate')
  24216.             BEGIN
  24217.                 ALTER TABLE dbo.MSreplication_queue ADD cmdstate bit DEFAULT 0 NOT NULL
  24218.                 IF @@ERROR <> 0
  24219.                     GOTO UNDO
  24220.             END    
  24221.  
  24222.             --
  24223.             -- change data column from text to varbinary(8000)
  24224.             -- SPECIAL CASE : since a simple ALTER does not work here
  24225.             -- we create a temp table to save the existing data and then
  24226.             -- recreate the table
  24227.             --
  24228.             if exists (select * from dbo.syscolumns 
  24229.                 where id = object_id('MSreplication_queue') and
  24230.                 name = 'data' and xtype = 34)
  24231.             begin
  24232.                 --
  24233.                 -- save existing column data
  24234.                 --
  24235.                 if exists (select * from dbo.MSreplication_queue)
  24236.                 begin
  24237.                     select @folddata = 1
  24238.                     create table #olddata (
  24239.                         publisher                    sysname collate database_default not null ,
  24240.                         publisher_db                sysname collate database_default not null ,
  24241.                         publication                    sysname collate database_default not null ,
  24242.                         tranid                        sysname collate database_default not null ,
  24243.                         data                        varbinary(8000) NULL ,
  24244.                         datalen                     int,
  24245.                         commandtype                    int,
  24246.                         insertdate                    datetime ,
  24247.                         orderkey                    bigint,
  24248.                         cmdstate                    bit)
  24249.                         
  24250.                     insert into #olddata 
  24251.                         select publisher, publisher_db, publication, tranid, CAST(data as varbinary(8000)), 
  24252.                                 datalen, commandtype, insertdate, orderkey, cmdstate 
  24253.                         from dbo.MSreplication_queue
  24254.                     if @@error != 0
  24255.                         goto UNDO
  24256.                 end
  24257.  
  24258.                 --
  24259.                 -- drop table
  24260.                 --
  24261.                 DROP TABLE dbo.MSreplication_queue
  24262.                 IF @@ERROR <> 0
  24263.                     GOTO UNDO                
  24264.             end        
  24265.         END
  24266.  
  24267.         --
  24268.         -- Create table if it does not exist
  24269.         --
  24270.         if NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE 
  24271.                 type = 'U' AND name = 'MSreplication_queue')        
  24272.         BEGIN        
  24273.             CREATE TABLE dbo.MSreplication_queue (
  24274.                 publisher                     sysname NOT NULL ,
  24275.                 publisher_db                 sysname NOT NULL ,
  24276.                 publication                 sysname NOT NULL ,
  24277.                 tranid                         sysname NOT NULL ,
  24278.                 data                         varbinary(8000) NULL ,
  24279.                 datalen                     int DEFAULT 0 ,
  24280.                 commandtype                 int NULL ,
  24281.                 insertdate                     datetime DEFAULT GETDATE(),
  24282.                 orderkey                    bigint IDENTITY(1,1) PRIMARY KEY,
  24283.                 cmdstate                    bit DEFAULT 0 NOT NULL
  24284.             )
  24285.             IF @@ERROR <> 0
  24286.                 GOTO UNDO
  24287.  
  24288.             /****
  24289.             CREATE NONCLUSTERED INDEX nc1MSreplication_queue ON
  24290.                     MSreplication_queue(tranid)
  24291.             IF @@ERROR <> 0
  24292.                 GOTO UNDO
  24293.             ****/
  24294.  
  24295.             EXEC @retcode = dbo.sp_MS_marksystemobject 'MSreplication_queue'
  24296.             if @retcode <> 0 or @@error <> 0
  24297.                 GOTO UNDO
  24298.  
  24299.             --
  24300.             -- Do we need to restore old data
  24301.             --
  24302.             if (@folddata = 1)
  24303.             begin
  24304.                 insert dbo.MSreplication_queue (publisher, publisher_db, publication, tranid, data,
  24305.                             datalen, commandtype, insertdate, cmdstate)
  24306.                     select publisher, publisher_db, publication, tranid, data, 
  24307.                                 datalen, commandtype, insertdate, cmdstate 
  24308.                         from #olddata
  24309.                         order by orderkey
  24310.                 if @@error != 0
  24311.                     goto UNDO
  24312.                 
  24313.                 drop table #olddata
  24314.                 if @@error != 0
  24315.                     goto UNDO
  24316.             end
  24317.         END
  24318.         --
  24319.         -- Table MSrepl_queuedtraninfo
  24320.         -- Create table if it does not exist
  24321.         --
  24322.         if NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE 
  24323.                 type = 'U' AND name = 'MSrepl_queuedtraninfo')
  24324.         BEGIN
  24325.             CREATE TABLE dbo.MSrepl_queuedtraninfo (
  24326.                 publisher                     sysname NOT NULL ,
  24327.                 publisher_db                     sysname NOT NULL ,
  24328.                 publication                     sysname NOT NULL ,
  24329.                 tranid                         sysname NOT NULL ,
  24330.                 maxorderkey                    bigint NOT NULL,
  24331.                 commandcount                bigint NOT NULL
  24332.             )
  24333.             IF @@ERROR <> 0
  24334.                 GOTO UNDO
  24335.             CREATE CLUSTERED INDEX nc1MSrepl_queuedtraninfo ON
  24336.                     MSrepl_queuedtraninfo(publisher,publisher_db,publication,tranid)
  24337.             IF @@ERROR <> 0
  24338.                 GOTO UNDO
  24339.             EXEC @retcode = dbo.sp_MS_marksystemobject 'MSrepl_queuedtraninfo'
  24340.             if @retcode <> 0 or @@error <> 0
  24341.                 GOTO UNDO
  24342.             --
  24343.             -- Populate this table as necessary
  24344.             --
  24345.             exec @retcode = dbo.sp_populateqtraninfo
  24346.             if @retcode <> 0 or @@error <> 0
  24347.                 GOTO UNDO
  24348.         END
  24349.         COMMIT TRAN
  24350.     END
  24351.  
  24352.     return(0)
  24353.     
  24354. UNDO:
  24355.     IF @@TRANCOUNT = 1
  24356.         ROLLBACK TRAN
  24357.     ELSE
  24358.         COMMIT TRAN  
  24359.     return(1) 
  24360. END
  24361. go
  24362.  
  24363. exec dbo.sp_MS_marksystemobject sp_MScreate_sub_tables
  24364. go
  24365.  
  24366. --
  24367. -- sp_MSupdate_mqserver_subdb
  24368. --
  24369. -- This procedure is called to upgrade the MSMQ related entries in 
  24370. -- MSsubscription_agents in subscription database - this processing 
  24371. -- cannot be done directly inside sp_MScreate_sub_tables since we need the 
  24372. -- queue_server column for the processing and we can get a syntax error 
  24373. -- if the table exists without the column
  24374. --
  24375. -- Assumption : MSsubscription_agents has been created 
  24376. --                and column queue_server exists
  24377. --
  24378. raiserror('Creating procedure sp_MSupdate_mqserver_subdb', 0,1)
  24379. GO
  24380. create procedure sp_MSupdate_mqserver_subdb
  24381. as
  24382. begin
  24383.     if exists (select * from dbo.MSsubscription_agents
  24384.         where queue_id IS NOT NULL and substring(queue_id, 1, 10) != N'mssqlqueue' and queue_server IS NULL)
  24385.     begin
  24386.         --
  24387.         -- we have entries for active Queued subscriptions using MSMQ that need upgrade
  24388.         --
  24389.         declare @queue_server sysname
  24390.                 ,@publisher sysname
  24391.                 ,@publisher_db sysname
  24392.                 ,@publication sysname
  24393.  
  24394.         DECLARE hC CURSOR LOCAL FAST_FORWARD FOR 
  24395.             select publisher, publisher_db, publication
  24396.             from dbo.MSsubscription_agents
  24397.             where queue_id IS NOT NULL 
  24398.                 and substring(queue_id, 1, 10) != N'mssqlqueue' 
  24399.                 and queue_server IS NULL
  24400.  
  24401.         OPEN hC
  24402.         FETCH hC INTO @publisher, @publisher_db, @publication
  24403.         WHILE (@@fetch_status != -1)
  24404.         BEGIN
  24405.             --
  24406.             -- the table MSsubscription_properties has to exist;
  24407.             -- prepare the queue server name from distributor name
  24408.             -- strip the instance name if necessary
  24409.             --
  24410.             select @queue_server = ISNULL(distributor, @@servername)
  24411.             from dbo.MSsubscription_properties
  24412.             where UPPER(publisher) = UPPER(@publisher) and
  24413.                         publisher_db = @publisher_db and
  24414.                         publication = @publication
  24415.  
  24416.             if (charindex(N'\', @queue_server) > 0)
  24417.                 select @queue_server = substring(@queue_server, 1, charindex(N'\', @queue_server) - 1)
  24418.  
  24419.             --
  24420.             -- set the queue_server for this entry
  24421.             --
  24422.             update dbo.MSsubscription_agents
  24423.             set queue_server = @queue_server
  24424.             where UPPER(publisher) = UPPER(@publisher) and
  24425.                         publisher_db = @publisher_db and
  24426.                         publication = @publication
  24427.  
  24428.             --
  24429.             -- get next entry
  24430.             --
  24431.             FETCH hC INTO @publisher, @publisher_db, @publication
  24432.         END
  24433.         CLOSE hC
  24434.         DEALLOCATE hC
  24435.     end
  24436. end
  24437. go
  24438. exec dbo.sp_MS_marksystemobject sp_MSupdate_mqserver_subdb
  24439. go
  24440.  
  24441. raiserror('Creating procedure sp_MS_replication_installed', 0,1)
  24442. GO
  24443.  
  24444. CREATE PROCEDURE sp_MS_replication_installed
  24445. as
  24446.     set nocount on
  24447.  
  24448.     declare @isinstalled int
  24449.     select @isinstalled = 0
  24450.     
  24451.     create table #keyvalues (keyvalue nvarchar(255) collate database_default not null, keyvaluedata nvarchar(255) collate database_default null)
  24452.  
  24453.     declare @instance sysname
  24454.     declare @regkey nvarchar(260)
  24455.     select @instance = convert(sysname, SERVERPROPERTY('InstanceName'))
  24456.     select @regkey = 'SOFTWARE\Microsoft\'
  24457.     -- default installation
  24458.     if @instance is null
  24459.         SELECT @regkey = @regkey + 'MSSQLServer\Replication' 
  24460.     else
  24461.         SELECT @regkey = @regkey + 'Microsoft SQL Server\' + @instance + '\Replication'
  24462.  
  24463.     insert into #keyvalues exec master..xp_regenumvalues 'HKEY_LOCAL_MACHINE',
  24464.         @regkey
  24465.     
  24466.     if @@ERROR <> 0
  24467.     begin
  24468.         drop table #keyvalues
  24469.         return (-1)
  24470.     end
  24471.  
  24472.     select @isinstalled = convert (int, (select keyvaluedata from #keyvalues where keyvalue = N'IsInstalled'))
  24473.     
  24474.     drop table #keyvalues
  24475.  
  24476.     if (@isinstalled is null or @isinstalled = 0)
  24477.     begin
  24478.         raiserror (21028, 16, -1)
  24479.         return (0)
  24480.     end
  24481.  
  24482.     return (1)
  24483. go
  24484. exec dbo.sp_MS_marksystemobject sp_MS_replication_installed
  24485. go
  24486.  
  24487. raiserror('Creating procedure sp_MSunc_to_drive', 0,1)
  24488. GO
  24489.  
  24490. CREATE PROCEDURE sp_MSunc_to_drive (
  24491.         @unc_path nvarchar(255), 
  24492.         @local_server sysname, 
  24493.         @local_path nvarchar(255) output
  24494.         )
  24495.     AS
  24496.  
  24497.     SET NOCOUNT ON
  24498.  
  24499.     declare @pattern nvarchar(150)
  24500.  
  24501.     select @pattern = N'\\' + upper(@local_server) + N'\'
  24502.  
  24503.     if    charindex(@pattern, upper(substring(@unc_path, 1, len(@pattern)))) <> 0 
  24504.         and charindex(N'$\', substring(@unc_path, len(@pattern)+2, 2))<>0
  24505.         select @local_path = substring(@unc_path, len(@pattern) + 1, 1) + N':' +
  24506.             substring(@unc_path, len(@pattern) + 3, len(@unc_path) - len(@pattern) -1)
  24507.     else
  24508.         select @local_path = @unc_path
  24509. GO
  24510. exec dbo.sp_MS_marksystemobject sp_MSunc_to_drive
  24511. go
  24512.  
  24513. raiserror('Creating procedure sp_MSretrieve_publication_attributes', 0,1)
  24514. GO
  24515. create proc sp_MSretrieve_publication_attributes 
  24516. @name             sysname,
  24517. @database         sysname
  24518. AS
  24519.  
  24520. SET NOCOUNT ON
  24521.  
  24522. declare @mergepublish_bit    int
  24523. declare @tranpublish_bit    int
  24524. declare @procname            nvarchar(640)
  24525. declare @retcode            int
  24526.  
  24527. select @mergepublish_bit    = 4 
  24528. select @tranpublish_bit     = 1
  24529.  
  24530. /*
  24531. ** Security Check, will be checked inside sp_MSretrieve_publication
  24532. ** and sp_MSretrieve_mergepublication
  24533. */
  24534.  
  24535. create table #publication_property (
  24536.     Name                     sysname collate database_default,
  24537.     dbanme                    sysname collate database_default,
  24538.     Publisher                sysname collate database_default,
  24539.     Type                    nvarchar(15) collate database_default,
  24540.     Description                nvarchar(255) collate database_default,
  24541.     Status                    tinyint,
  24542.     allow_pull                bit,
  24543.     allow_sync_tran            bit,
  24544.     allow_anonymous            bit,
  24545.     allow_queued_tran        bit,
  24546.     enabled_for_internet    bit,
  24547.     third_party                bit
  24548. )
  24549.  
  24550. if (select category & @tranpublish_bit from master..sysdatabases where name = @database collate database_default) <> 0
  24551.     begin
  24552.         select @procname = quotename(@database) + '.dbo.sp_MSretrieve_publication '
  24553.         insert into #publication_property exec @retcode = @procname @name
  24554.     end
  24555.  
  24556. if (select category & @mergepublish_bit from master..sysdatabases where name = @database collate database_default) <> 0
  24557.     begin
  24558.         select @procname = quotename(@database) + '.dbo.sp_MSretrieve_mergepublication '
  24559.         insert into #publication_property exec @retcode = @procname @name
  24560.     end
  24561. select * from #publication_property
  24562. drop table #publication_property
  24563. Go
  24564. exec dbo.sp_MS_marksystemobject sp_MSretrieve_publication_attributes
  24565. go
  24566.  
  24567. raiserror('Creating procedure sp_MScleanup_publication_ADinfo', 0,1)
  24568. GO
  24569. create proc sp_MScleanup_publication_ADinfo 
  24570. @name             sysname,
  24571. @database         sysname
  24572. AS
  24573.  
  24574. SET NOCOUNT ON
  24575.  
  24576. declare @mergepublish_bit    int
  24577. declare @tranpublish_bit    int
  24578. declare @cmd            nvarchar(640)
  24579.  
  24580. select @mergepublish_bit    = 4 
  24581. select @tranpublish_bit     = 1
  24582.  
  24583. /*
  24584. ** Security Check
  24585. */
  24586. select @cmd = quotename(@database) + '.dbo.sp_MSreplcheck_publish'
  24587. exec (@cmd)
  24588. IF @@ERROR <> 0
  24589.     return (1)
  24590.  
  24591. if (select category & @tranpublish_bit from master..sysdatabases where name = @database collate database_default) <> 0
  24592.     begin
  24593.         select @cmd = N'update' + quotename(@database) + N'.dbo.syspublications set ad_guidname=NULL where name=N' + quotename(@name, N'''')
  24594.         exec (@cmd)
  24595.     end
  24596.  
  24597. if (select category & @mergepublish_bit from master..sysdatabases where name = @database collate database_default) <> 0
  24598.     begin
  24599.         select @cmd = N'update' + quotename(@database) + N'.dbo.sysmergepublications set ad_guidname=NULL where name=N' + quotename(@name, N'''')
  24600.         exec (@cmd)
  24601.     end
  24602. Go
  24603. exec dbo.sp_MS_marksystemobject sp_MScleanup_publication_ADinfo
  24604. go
  24605.  
  24606. raiserror('Creating procedure sp_MSrepl_linkedservers_rowset', 0,1)
  24607. GO
  24608. create proc sp_MSrepl_linkedservers_rowset @srvname sysname
  24609. as
  24610.     select
  24611.         SVR_NAME         = srvname,
  24612.         SVR_PRODUCT        = srvproduct,
  24613.         SVR_PROVIDERNAME    = providername,
  24614.         SVR_DATASOURCE        = datasource,
  24615.         SVR_PROVIDERSTRING    = providerstring,
  24616.         SVR_LOCATION        = location,
  24617.         SVR_CATALOG        = catalog
  24618.     from master.dbo.sysservers
  24619.     where UPPER(srvname) = UPPER(@srvname) collate database_default and 
  24620.     isnull(providername,' ') <> ' ' and
  24621.     ( isnull(datasource, ' ') <> ' ' or
  24622.     isnull(location, ' ') <> ' ' or
  24623.     isnull(providerstring, ' ') <> ' '  or
  24624.     isnull(catalog, ' ') <> ' ' )
  24625.     order by 1    
  24626.  
  24627.     if @@error <> 0
  24628.         return 1
  24629.     else
  24630.         return 0
  24631. go
  24632. exec dbo.sp_MS_marksystemobject sp_MSrepl_linkedservers_rowset
  24633. go
  24634.  
  24635.  
  24636.  
  24637. raiserror('Creating procedure sp_MSregistersubscription', 0,1)
  24638. go
  24639.  
  24640. CREATE PROCEDURE sp_MSregistersubscription (
  24641.     @replication_type            int, /* Transactional = 1, Merge = 2 */
  24642.     @publisher                     sysname,
  24643.     @publisher_db                 sysname,
  24644.     @publisher_security_mode    int = NULL,                        /* 0 standard; 1 integrated */
  24645.     @publisher_login            sysname = NULL,
  24646.     @publisher_password    nvarchar(524) = NULL,
  24647.     @publication                 sysname,         
  24648.     @subscriber                 sysname,
  24649.     @subscriber_db                 sysname,
  24650.     @subscriber_security_mode    int = NULL,                        /* 0 standard; 1 integrated */
  24651.     @subscriber_login            sysname = NULL,
  24652.     @subscriber_password        nvarchar(524) = NULL,
  24653.     @distributor                 sysname,
  24654.     @distributor_security_mode     int = NULL,
  24655.     @distributor_login             sysname = NULL,
  24656.     @distributor_password        nvarchar(524) = NULL,
  24657.     @subscription_id            uniqueidentifier ,
  24658.     @independent_agent            int = NULL,
  24659.     @subscription_type            int,
  24660.     @use_interactive_resolver    int = NULL,
  24661.     @failover_mode                int = NULL
  24662.     ) AS
  24663.  
  24664.     SET NOCOUNT ON
  24665.  
  24666.     /* MobileSync Support */
  24667.     declare @subscription_name                nvarchar(1000)
  24668.     declare @regkey                            nvarchar(1000)
  24669.     declare @subidstr                        nvarchar(38)
  24670.     declare @profile_name                     nvarchar(100)
  24671.     declare @retcode                        int
  24672.     
  24673.     set @subscription_name = @publisher + ':' + @publisher_db + ':' + @publication + ':' + @subscriber + ':' + @subscriber_db
  24674.     /* Replace back slash with forward slash so that the key name is a valid REGISTRY key name */
  24675.     set @subscription_name = REPLACE(@subscription_name,'\','/')
  24676.     set @regkey = 'SOFTWARE\Microsoft\Microsoft SQL Server\80\Replication\Subscriptions\' + @subscription_name
  24677.     set @subidstr = '{' + convert ( nchar(36), @subscription_id) + '}'
  24678.     set @profile_name = formatmessage(20550) -- SyncMgr Profile
  24679.  
  24680.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  24681.                                @regkey,
  24682.                                'ProfileName',
  24683.                                'REG_SZ',
  24684.                                 @profile_name    
  24685.     if @retcode <> 0 OR @@ERROR <> 0
  24686.         return 1
  24687.  
  24688.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  24689.                                @regkey,
  24690.                                'ReplicationType',
  24691.                                'REG_DWORD',
  24692.                                 @replication_type    
  24693.     if @retcode <> 0 OR @@ERROR <> 0
  24694.         return 1
  24695.  
  24696.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  24697.                                @regkey,
  24698.                                'SubscriptionType',
  24699.                                'REG_DWORD',
  24700.                                 @subscription_type    
  24701.     if @retcode <> 0 OR @@ERROR <> 0
  24702.         return 1
  24703.  
  24704.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  24705.                                @regkey,
  24706.                                'Subid',
  24707.                                'REG_SZ',
  24708.                                 @subidstr    
  24709.     if @retcode <> 0 OR @@ERROR <> 0
  24710.         return 1
  24711.  
  24712.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  24713.                                @regkey,
  24714.                                'Publisher',
  24715.                                'REG_SZ',
  24716.                                 @publisher                                        
  24717.     if @retcode <> 0 OR @@ERROR <> 0
  24718.         return 1
  24719.  
  24720.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  24721.                                @regkey,
  24722.                                'PublisherDb',
  24723.                                'REG_SZ',
  24724.                                 @publisher_db
  24725.     if @retcode <> 0 OR @@ERROR <> 0
  24726.         return 1
  24727.  
  24728.     
  24729.     IF @use_interactive_resolver IS NOT NULL
  24730.     BEGIN
  24731.         EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  24732.                                @regkey,
  24733.                                'UseInteractiveResolver',
  24734.                                'REG_DWORD',
  24735.                                 @use_interactive_resolver
  24736.         if @retcode <> 0 OR @@ERROR <> 0
  24737.             return 1
  24738.     END
  24739.  
  24740.     /* If Publisher security mode is NOT NULL, write out the entries */
  24741.     if @publisher_security_mode IS NOT NULL
  24742.         begin
  24743.                EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  24744.                                        @regkey,
  24745.                                        'PublisherSecurityMode',
  24746.                                        'REG_DWORD',
  24747.                                         @publisher_security_mode
  24748.             if @retcode <> 0 OR @@ERROR <> 0
  24749.                 return 1
  24750.  
  24751.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  24752.                                        @regkey,
  24753.                                        'PublisherLogin',
  24754.                                        'REG_SZ',
  24755.                                         @publisher_login                                    
  24756.             if @retcode <> 0 OR @@ERROR <> 0
  24757.                 return 1
  24758.  
  24759.         end
  24760.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  24761.                                @regkey,
  24762.                                'Publication',
  24763.                                'REG_SZ',
  24764.                                 @publication
  24765.     if @retcode <> 0 OR @@ERROR <> 0
  24766.         return 1
  24767.  
  24768.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  24769.                                @regkey,
  24770.                                'Subscriber',
  24771.                                'REG_SZ',
  24772.                                 @subscriber
  24773.     if @retcode <> 0 OR @@ERROR <> 0
  24774.         return 1
  24775.  
  24776.     /* If Subscriber security mode is NOT NULL, write out the entries */
  24777.     if @subscriber_security_mode IS NOT NULL
  24778.         begin
  24779.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  24780.                                @regkey,
  24781.                                'SubscriberSecurityMode',
  24782.                                'REG_DWORD',
  24783.                                 @subscriber_security_mode
  24784.             if @retcode <> 0 OR @@ERROR <> 0
  24785.                 return 1
  24786.  
  24787.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  24788.                                @regkey,
  24789.                                'SubscriberLogin',
  24790.                                'REG_SZ',
  24791.                                 @subscriber_login                                    
  24792.             if @retcode <> 0 OR @@ERROR <> 0
  24793.                 return 1
  24794.  
  24795.         end
  24796.  
  24797.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  24798.                                @regkey,
  24799.                                'SubscriberDb',
  24800.                                'REG_SZ',
  24801.                                 @subscriber_db                                    
  24802.     if @retcode <> 0 OR @@ERROR <> 0
  24803.         return 1
  24804.                 
  24805.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  24806.                                @regkey,
  24807.                                'Distributor',
  24808.                                'REG_SZ',
  24809.                                 @distributor
  24810.     if @retcode <> 0 OR @@ERROR <> 0
  24811.         return 1
  24812.  
  24813.     /* If Distributor security mode is NOT NULL, write out the entries */
  24814.     if @distributor_security_mode IS NOT NULL
  24815.         begin
  24816.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  24817.                                @regkey,
  24818.                                'DistributorSecurityMode',
  24819.                                'REG_DWORD',
  24820.                                 @distributor_security_mode
  24821.             if @retcode <> 0 OR @@ERROR <> 0
  24822.                 return 1
  24823.  
  24824.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  24825.                                @regkey,
  24826.                                'DistributorLogin',
  24827.                                'REG_SZ',
  24828.                                 @distributor_login                                    
  24829.             if @retcode <> 0 OR @@ERROR <> 0
  24830.                 return 1
  24831.  
  24832.         end
  24833.  
  24834.     if @independent_agent IS NOT NULL
  24835.         begin
  24836.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  24837.                                @regkey,
  24838.                                'IndependentAgent',
  24839.                                'REG_DWORD',
  24840.                                 @independent_agent    
  24841.             if @retcode <> 0 OR @@ERROR <> 0
  24842.                 return 1
  24843.         end                
  24844.  
  24845.     IF @failover_mode IS NOT NULL
  24846.         begin
  24847.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  24848.                                @regkey,
  24849.                                'FailoverMode',
  24850.                                'REG_DWORD',
  24851.                                 @failover_mode    
  24852.             if @retcode <> 0 OR @@ERROR <> 0
  24853.                 return 1
  24854.  
  24855.         end            
  24856.  
  24857.     -- Mark enabled_for_syncmgr bit if every thing succeeded.
  24858.     -- If the row exists in MSreplication_properties table, 
  24859.     -- set enabled_for_syncmgr bit
  24860.     -- The logic need to be here because UI call this sp directly.
  24861.     if exists (select * from sysobjects where name = 'MSsubscription_properties')
  24862.     begin
  24863.         update MSsubscription_properties set enabled_for_syncmgr = 1 where
  24864.             UPPER(publisher) = UPPER(@publisher)
  24865.             and publisher_db =  @publisher_db
  24866.             and publication = @publication
  24867.         if @retcode <> 0 OR @@ERROR <> 0
  24868.             return 1
  24869.     end
  24870.  
  24871.     return 0
  24872. GO
  24873.  
  24874. raiserror('Creating procedure sp_MSunregistersubscription', 0,1)
  24875. go
  24876.  
  24877. CREATE PROCEDURE sp_MSunregistersubscription
  24878.         @publisher         sysname = NULL, 
  24879.         @publisher_db     sysname = NULL, 
  24880.         @publication     sysname = NULL, 
  24881.         @subscriber     sysname = NULL,
  24882.         @subscriber_db     sysname = NULL
  24883.     AS
  24884.  
  24885.     /* 
  24886.     ** Drop the corresponding registry entry for MobileSync
  24887.     */
  24888.     declare @enabled            int
  24889.     declare    @retcode             int
  24890.     declare @regkey                nvarchar(1000)
  24891.     
  24892.     select @retcode = 0
  24893.     -- Mark enabled_for_syncmgr bit before trying to delete the key
  24894.     -- If the row exists in MSreplication_properties table, 
  24895.     -- set enabled_for_syncmgr bit
  24896.     -- The logic need to be here because UI call this sp directly.
  24897.     if exists (select * from sysobjects where name = 'MSsubscription_properties')
  24898.     begin
  24899.         update MSsubscription_properties set enabled_for_syncmgr = 0 where
  24900.             UPPER(publisher) = UPPER(@publisher)
  24901.             and publisher_db =  @publisher_db
  24902.             and publication = @publication
  24903.         if @@ERROR <> 0
  24904.             return 1
  24905.     end
  24906.  
  24907.     -- regdelete returns 'Access Denied' message if key does not exist; check before delete
  24908.     exec sp_MSsubscription_enabled_for_syncmgr
  24909.         @publisher, @publisher_db, @publication, @subscriber, @subscriber_db, @enabled OUT, @regkey OUT
  24910.     if @@ERROR <> 0
  24911.         return 1
  24912.         
  24913.     if @enabled = 1
  24914.         begin
  24915.             EXECUTE @retcode = master.dbo.xp_regdeletekey 'HKEY_LOCAL_MACHINE', @regkey
  24916.             if @@error <> 0 OR @retcode <> 0
  24917.                 return 1
  24918.         end
  24919.  
  24920.     return 0        
  24921.  
  24922. GO
  24923.  
  24924. raiserror('Creating procedure sp_MSsubscription_enabled_for_syncmgr', 0,1)
  24925. go
  24926.  
  24927. CREATE PROCEDURE sp_MSsubscription_enabled_for_syncmgr
  24928.         @publisher         sysname = NULL, 
  24929.         @publisher_db     sysname = NULL, 
  24930.         @publication     sysname = NULL, 
  24931.         @subscriber     sysname = NULL,
  24932.         @subscriber_db     sysname = NULL,
  24933.         @enabled        int = NULL OUTPUT,
  24934.         @regkey            nvarchar(1000) = NULL OUTPUT
  24935.     AS
  24936.  
  24937.     /* 
  24938.     ** Drop the corresponding registry entry for MobileSync
  24939.     */
  24940.     declare @subscription_name     nvarchar(1000)
  24941.     declare @keyexist            int
  24942.     
  24943.     -- no reg key to clean up for virtual subscribers
  24944.     if @subscriber is null
  24945.     begin
  24946.         select @enabled = 0
  24947.         return 0
  24948.     end
  24949.     
  24950.     set @subscription_name = @publisher + ':' + @publisher_db + ':' + @publication + ':' + @subscriber + ':' + @subscriber_db
  24951.     /* Replace back slash with forward slash so that the key name is a valid REGISTRY key name */
  24952.     set @subscription_name = REPLACE(@subscription_name,'\','/')
  24953.     set @regkey = 'SOFTWARE\Microsoft\Microsoft SQL Server\80\Replication\Subscriptions\' + @subscription_name
  24954.     create table #keyexist (keyexist int)
  24955.     insert into #keyexist EXECUTE master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', @regkey
  24956.     select @enabled = keyexist from #keyexist
  24957.     drop table #keyexist
  24958.     return 0        
  24959.  
  24960. GO
  24961.  
  24962.  
  24963. raiserror('Creating procedure sp_MSget_jobstate', 0,1)
  24964. go
  24965.  
  24966. -- Procedure sp_MSget_jobstate
  24967. --    The proc takes a specific Job ID and returns the Job State of the job
  24968. --        Returns a row with one column job_state
  24969. --        Returns a row with NULL if job does not exist
  24970. -- 
  24971.  
  24972. CREATE PROCEDURE sp_MSget_jobstate
  24973.     @job_id             UNIQUEIDENTIFIER
  24974. AS
  24975. BEGIN
  24976.     DECLARE @is_sysadmin INT
  24977.     DECLARE @job_owner   sysname
  24978.     DECLARE @job_state   INT 
  24979.     DECLARE @job_id_as_char VARCHAR(36)
  24980.  
  24981.     SET NOCOUNT ON
  24982.  
  24983.     CREATE TABLE #xp_results (job_id                UNIQUEIDENTIFIER NOT NULL,
  24984.                             last_run_date         INT              NOT NULL,
  24985.                             last_run_time         INT              NOT NULL,
  24986.                             next_run_date         INT              NOT NULL,
  24987.                             next_run_time         INT              NOT NULL,
  24988.                             next_run_schedule_id  INT              NOT NULL,
  24989.                             requested_to_run      INT              NOT NULL, -- BOOL
  24990.                             request_source        INT              NOT NULL,
  24991.                             request_source_id     sysname          collate database_default null,
  24992.                             running               INT              NOT NULL, -- BOOL
  24993.                             current_step          INT              NOT NULL,
  24994.                             current_retry_attempt INT              NOT NULL,
  24995.                             job_state             INT              NOT NULL)
  24996.  
  24997.     -- Need a job_id
  24998.     if (@job_id IS NULL)
  24999.     BEGIN
  25000.         SELECT @job_id_as_char = CONVERT(VARCHAR(36), @job_id)
  25001.         RAISERROR(14262, -1, -1, '@job_id', @job_id_as_char)
  25002.         RETURN(1) -- Failure
  25003.     END
  25004.  
  25005.     -- Capture job execution information (for local jobs only since that's all SQLServerAgent caches)
  25006.     SELECT @is_sysadmin = ISNULL(IS_SRVROLEMEMBER(N'sysadmin'), 0)
  25007.     SELECT @job_owner = suser_sname(suser_sid())
  25008.     INSERT INTO #xp_results
  25009.     EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner
  25010.  
  25011.     -- Select the job state of the job in question
  25012.     SELECT @job_state = job_state FROM #xp_results WHERE @job_id = job_id
  25013.  
  25014.     -- Error if we have no rows selected
  25015.     if (@job_state IS NULL)
  25016.     BEGIN
  25017.         SELECT @job_id_as_char = CONVERT(VARCHAR(36), @job_id)
  25018.         RAISERROR(14262, -1, -1, '@job_id', @job_id_as_char)
  25019.         RETURN(1) -- Failure
  25020.     END
  25021.     ELSE
  25022.         SELECT @job_state
  25023.     
  25024.     -- All done
  25025.     DROP TABLE #xp_results
  25026.     RETURN(0)    -- Success
  25027. END
  25028. GO
  25029.  
  25030. raiserror('Creating procedure sp_MSscript_pkvar_assignment', 0,1)
  25031. go
  25032. create procedure sp_MSscript_pkvar_assignment
  25033. (
  25034.     @objid          int,
  25035.     @columns      binary(32), 
  25036.     @indent       int = 0,
  25037.     @identity_col sysname = NULL, -- Not null value used by trigger scripting
  25038.     @ts_col       sysname = NULL,  -- Not null value used by trigger scripting
  25039.     @primary_key_bitmap varbinary(4000) = null, -- NULL when synctran processing
  25040.     @fisqueuedpub bit = 0  -- 1 = processing a queued publication on publisher
  25041. )
  25042. as
  25043. begin
  25044.     -- This stored procedure will assign the '_old' var to new var
  25045.     -- based on @bitmap. This is to avoid using case statement
  25046.     -- in the where clause in the synctran pub proc, which
  25047.     -- will cause a table scan.
  25048.     declare @cmd          nvarchar(4000)
  25049.         ,@spacer       nvarchar(20)
  25050.         ,@indkey       int
  25051.         ,@indid        int
  25052.         ,@this_col     int
  25053.         ,@col          sysname
  25054.         ,@qualname     nvarchar(512)
  25055.         ,@column          nvarchar(255)
  25056.         ,@key          sysname
  25057.         ,@src_cols      int
  25058.         ,@total_col        int
  25059.         ,@fcreatedcolmap    bit
  25060.         ,@art_col int -- relative position of column
  25061.     declare @colmap table (relativeorder int identity(1,1), colid int)
  25062.  
  25063.     select @spacer = N'select '
  25064.         ,@cmd = N''
  25065.         ,@indkey = 1
  25066.         ,@indid = 0
  25067.         ,@fcreatedcolmap = 0
  25068.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  25069.     select @src_cols = max(colid)
  25070.             ,@total_col = count(colid)
  25071.         from syscolumns where id = @objid
  25072.     exec dbo.sp_MSpad_command @cmd output, @indent
  25073.     exec dbo.sp_MSflush_command @cmd output, 1, @indent
  25074.  
  25075.     if @primary_key_bitmap is null
  25076.     begin
  25077.         exec @indid = dbo.sp_MStable_has_unique_index @objid
  25078.         if @indid is null
  25079.         begin
  25080.             raiserror('Debug: Cannot find unique index', 16, -1)
  25081.             return (1)
  25082.         end
  25083.     end
  25084.  
  25085.     --
  25086.     -- check if column Id match relative column order
  25087.     -- for trigger scripting
  25088.     --
  25089.     if ((@total_col < @src_cols) and 
  25090.         (@columns is null) and (@primary_key_bitmap is not null))
  25091.     begin
  25092.         --
  25093.         -- this table may have altered columns, so when we need to 
  25094.         -- set a mapping for using the bitmaps properly as the bitmap
  25095.         -- always refers relative column order
  25096.         --
  25097.         insert into @colmap (colid)
  25098.             select colid from syscolumns where id = @objid order by colid
  25099.         if (@@error != 0)
  25100.         begin
  25101.             raiserror('Could not create column mapping', 16, -1)
  25102.             return (1)
  25103.         end
  25104.         select @fcreatedcolmap = 1
  25105.     end
  25106.  
  25107.     while (1=1)
  25108.     begin
  25109.         if @primary_key_bitmap is null 
  25110.         begin
  25111.             select @key = index_col(@qualname, @indid, @indkey)
  25112.             if @key is null
  25113.                 break
  25114.             exec dbo.sp_MSget_col_position @objid, @columns, @key, @col output, 0, NULL, @this_col output
  25115.         end
  25116.         else
  25117.         begin
  25118.             exec dbo.sp_MSget_map_position @primary_key_bitmap, @indkey, @col output, @this_col output
  25119.             if @this_col is null
  25120.                 break
  25121.  
  25122.                 --
  25123.                 -- set the actual column id for this relative order in the PK bitmap if necessary
  25124.                 --
  25125.             if (@fcreatedcolmap = 1)
  25126.             begin
  25127.                 select @art_col = @this_col
  25128.                 select @this_col = colid
  25129.                     ,@col = 'c' + convert(sysname, colid) 
  25130.                 from @colmap 
  25131.                 where relativeorder = @art_col 
  25132.             end
  25133.             else
  25134.             begin
  25135.                 select @art_col = NULL
  25136.             end
  25137.  
  25138.             -- Get column name
  25139.             exec dbo.sp_MSget_colinfo @objid, @this_col, @columns, 0, @key output
  25140.         end
  25141.         select @indkey = @indkey + 1
  25142.         --
  25143.         -- check if identity/timestamp column were specified
  25144.         -- for skipping during subscriber trigger scripting
  25145.         --
  25146.         if @key in (@identity_col, @ts_col)
  25147.             continue
  25148.         --
  25149.         -- If we are scripting on publisher 
  25150.         --
  25151.         if (@primary_key_bitmap is null)
  25152.         begin
  25153.             declare @isset int
  25154.             --
  25155.             -- skip column if not replicated
  25156.             --
  25157.             exec @isset = dbo.sp_isarticlecolbitset @this_col, @columns
  25158.             if (@isset != 1)
  25159.                 continue
  25160.             --
  25161.             -- skip timestamp processing for queued
  25162.             --
  25163.             if ((@fisqueuedpub = 1) and 
  25164.                 exists (select name from syscolumns 
  25165.                     where id = @objid and colid = @this_col and xtype = 189))
  25166.                 continue
  25167.         end
  25168.  
  25169.         select @cmd = @spacer + N'@c' + convert(nvarchar(10), @this_col)
  25170.  
  25171.         -- Get the new values for the columns in primary key.
  25172.         exec dbo.sp_MSget_synctran_column 
  25173.             @ts_col = null,
  25174.             @op_type = null , -- 'ins, 'upd', 'del'
  25175.             @is_new = null,
  25176.             @primary_key_bitmap = null,
  25177.             @colname = null,
  25178.             @this_col = @this_col,
  25179.             @column = @column output,
  25180.             @from_proc = 0,
  25181.             @coltype = null,
  25182.             @type = 'pk_var',
  25183.             @art_col = @art_col
  25184.             select @cmd = @cmd + N' = ' + @column 
  25185.             select @spacer = ',
  25186.     '
  25187.  
  25188.         -- flush command if necessary
  25189.         exec dbo.sp_MSflush_command @cmd output, 1, @indent
  25190.     end
  25191.  
  25192. end
  25193. go
  25194. EXEC dbo.sp_MS_marksystemobject sp_MSscript_pkvar_assignment
  25195. GO
  25196.  
  25197. raiserror('Creating procedure sp_MSget_publication_from_taskname', 0,1)
  25198. go
  25199. create procedure sp_MSget_publication_from_taskname
  25200.     @taskname     sysname,
  25201.     @publisher    sysname, 
  25202.     @publisherdb  sysname,
  25203.     @publication  sysname OUTPUT
  25204. as
  25205.     declare @value       sysname
  25206.     declare @value2      sysname
  25207.     declare @position    INT
  25208.  
  25209.     select @publication = NULL
  25210.  
  25211.     -- Parse out publication name from the task name "publisher_publisherdb_publication_number"
  25212.     -- Expect publisher name
  25213.     if charindex(@publisher, @taskname) <> 1
  25214.     begin
  25215.         return 1
  25216.     end   
  25217.  
  25218.     -- Eat up the publisher name
  25219.     select @value = stuff(@taskname, 1, len(@publisher), N'')  
  25220.  
  25221.     -- Expect '_' + publisherdb + '_'
  25222.     select @value2 = N'_' + @publisherdb + N'_'
  25223.     if charindex(@value2, @value) <> 1
  25224.     begin
  25225.         return 1
  25226.     end
  25227.  
  25228.     -- Eat up '_' + publisherdb + '_'
  25229.     select  @value = stuff(@value, 1, LEN(@publisherdb) + 2, N'')
  25230.       
  25231.     -- Reverse the string in the hope of finding the first '_' 
  25232.     -- from the right which denotes the end of the publication 
  25233.     -- name. The number at the end should not contain '_'
  25234.     select @value2 = reverse(@value)
  25235.     select @position = charindex(N'_', @value2)
  25236.     if @position < 2
  25237.     begin
  25238.         return 1
  25239.     end
  25240.        
  25241.     select @publication = left(@value, len(@value) - @position)      
  25242.     return 0
  25243. go
  25244.  
  25245. EXEC dbo.sp_MS_marksystemobject sp_MSget_publication_from_taskname
  25246. go
  25247.  
  25248. -- sp_MSacquireHeadofQueueLock, sp_MSacquireSlotLock and sp_MSreleaseSlotLock work together
  25249. -- to ensure the number of concurrent merge processes does not exceed a given value. A merge
  25250. -- process has to acquire headofqueue, i.e., Im-First lock before it can acquire slot lock. 
  25251. -- All merge processes are queued for the Im-First lock and only the one process holding that
  25252. -- lock will poll to see if there is any slot available for it to get it.
  25253.  
  25254. raiserror('Creating procedure sp_MSacquireHeadofQueueLock', 0,1)
  25255. GO
  25256.  
  25257. CREATE PROC sp_MSacquireHeadofQueueLock 
  25258. @process_name                    sysname,
  25259. @queue_timeout                    int = 0,  -- means wait inâ•–definitely
  25260. @no_result                      bit = 0,
  25261. @return_immediately                bit = 0      -- if 1, do not wait: return and post a progress message.
  25262. AS
  25263. declare @entry_date        datetime
  25264. declare @delay_time        int --in second
  25265. declare @retcode         int
  25266. declare @max_waiting    int
  25267. declare @lock_acquired    bit
  25268.  
  25269. -- Security Checking 
  25270. -- sysadmin or db_owner or PAL user of any publication
  25271. if not exists (select * from dbo.sysmergepublications 
  25272.                     where 1 = {fn ISPALUSER(pubid)})
  25273. begin
  25274.     RAISERROR (14260, 16, -1)
  25275.     return (1)
  25276. end
  25277.  
  25278. if @queue_timeout<0
  25279.     begin
  25280.         raiserror(21344, 16, -1, '@queue_timeout')
  25281.         return (1)        
  25282.     end
  25283.         
  25284. if @queue_timeout> 3600*12 -- more than 12 hours is not allowed: make it 0 in this case.
  25285.     begin
  25286.         raiserror(21417, 16, -1) 
  25287.         return (1)
  25288.     end
  25289.  
  25290. --quick peek and leave
  25291. if @return_immediately=1
  25292.     begin
  25293.         --take a peek: return without wait regardless of whether the lock is successfully acquired.
  25294.         exec @retcode=sp_getapplock @Resource=@process_name,@LockMode=N'Exclusive',@LockOwner='Session',@LockTimeout=0
  25295.         if (@retcode <> 0 AND @retcode <> -1)
  25296.             begin
  25297.                 RAISERROR(21414,16,-1)
  25298.                 RETURN(@retcode)
  25299.             end
  25300.         IF (@retcode = 0)       -- AppLock acquired
  25301.             select 1, 0         -- 1 means lock acquired, 0 is the time consumed to acquired this lock.
  25302.         else if @retcode = -1    -- AppLock is not available    
  25303.             select 0, 0            -- first 0 means lock not available, second column will be ignored.
  25304.         return (0)                -- OK
  25305.     end        
  25306.  
  25307. -- from now on, @return_immediately=0
  25308. --if @queue_timeout=0, means waiting indefinitely
  25309. if @queue_timeout=0
  25310.     select @max_waiting = NULL
  25311. else
  25312. --otherwise convert to minisecond and pass it down.
  25313.     select @max_waiting = @queue_timeout * 1000
  25314.  
  25315.  
  25316. select @delay_time=0
  25317. select @entry_date=getdate()
  25318.  
  25319. -- First try to acquire EXCLUSIVE lock which signfies at front of queue.   i.e. I'm next.
  25320.  
  25321. exec @retcode=sp_getapplock @process_name, @LockMode=N'Exclusive',@LockOwner=N'Session', @LockTimeout=@max_waiting
  25322. -- We shouldn't return from above until we have it 
  25323. -- RC should be either 0 (got immediately) or 1 (waited and got it eventually) or -1 (timed out); Exit on anything else.
  25324. -- We need value -1 because @LockTimeout value is no longer NULL, meaning waiting indefinitely. It is possible 
  25325. -- that we waited for a given length of time and timed out
  25326. IF (@retcode <> 0 and @retcode <> 1) and @retcode<>-1
  25327.     BEGIN
  25328.         RAISERROR(21413, 16, -1)
  25329.         RETURN(@retcode)
  25330.     END
  25331.     
  25332. -- Im-first lock is to be released after successfully obtained a slot lock later.
  25333. select @delay_time=datediff(ss, @entry_date, getdate())
  25334. if @retcode=-1
  25335.     select @lock_acquired=0
  25336. else
  25337.     select @lock_acquired=1
  25338.  
  25339. if @no_result = 0
  25340. begin
  25341.     select @lock_acquired, @delay_time
  25342. end
  25343.  
  25344. RETURN(0)
  25345.  
  25346. exec dbo.sp_MS_marksystemobject sp_MSacquireHeadofQueueLock
  25347. go
  25348.  
  25349. grant execute on dbo.sp_MSacquireHeadofQueueLock to public
  25350. go
  25351.  
  25352. -- this stored procedure is called by merge agent to limit the max number of
  25353. -- concurrent merge processes at publisher side. The merge process that calls
  25354. -- this SP must be the one that is currently holding HeadOfQueue lock. Once
  25355. -- a slot lock is granted, HeadOfQueue lock will be released for use the next
  25356. -- merge process waiting in the queue for that lock.
  25357. -- @queue_timeout value gives
  25358. -- the maximum length of time (in seconds) a merge agent would like to wait
  25359. -- before acquring Im-first lock and the available serve slots. A value of 0
  25360. -- means it would wait indefinitely until getting the lock or being canceled
  25361. -- by the caller of the procedure
  25362.  
  25363. raiserror('Creating procedure sp_MSacquireSlotLock', 0,1)
  25364. GO
  25365.  
  25366. CREATE PROC sp_MSacquireSlotLock 
  25367. @process_name                    sysname,
  25368. @concurrent_max                 int,
  25369. @queue_timeout                    int = 0,-- means wait inâ•–definitely
  25370. @return_immediately                bit = 0 -- if set to 1, take a peek at the server and return immediately.
  25371.  
  25372. AS
  25373. declare @entry_date        datetime
  25374. declare @slot_name         nvarchar(150)  -- OUTPUT - must give back slot acquired to caller so caller can later release.
  25375. declare @basetime         datetime
  25376. declare @delaytime         datetime
  25377. declare @retcode         int
  25378. declare @i                int
  25379. declare @lock_acquired  bit
  25380.  
  25381. -- Security Checking 
  25382. if not exists (select * from dbo.sysmergepublications 
  25383.                     where 1 = {fn ISPALUSER(pubid)})
  25384. begin
  25385.     RAISERROR (15247, 11, -1)
  25386.     return (1)
  25387. end
  25388.  
  25389. select @lock_acquired = 0
  25390. if @queue_timeout<0
  25391.     begin
  25392.         raiserror(21344, 16, -1, '@queue_timeout')
  25393.         return (1)        
  25394.     end
  25395.     
  25396. if @concurrent_max<=0
  25397.     begin
  25398.         raiserror(21344, 16, -1, '@concurrent_max')
  25399.         return (1)        
  25400.     end
  25401.         
  25402. select @entry_date=getdate()
  25403. select @delaytime = '00:00:02' --polling interval is defaulted to 2 seconds
  25404.  
  25405. SET @slot_name=NULL -- If terminate anywhere unexpectedly, dont want to give caller a lock they didnt really get.
  25406.  
  25407. -- We are at front of queue, so check if any available 'slot' is open.   
  25408. -- We do not wait at all for these locks, and hence expect either it was granted or timed out (-1).
  25409.  
  25410. SET @i=1
  25411.  
  25412. WHILE (@i <= @concurrent_max)
  25413.     BEGIN
  25414.         --the process has waited long enough. quit now and try later. If @queue_timeout is 0, keep waiting until succeeds.
  25415.         if @queue_timeout>0 and DATEADD(second, -@queue_timeout,  getdate()) > @entry_date
  25416.             begin
  25417.                 select @lock_acquired = 1 -- not a peek but has waited as specified
  25418.                 select @slot_name = NULL -- waited but failed to get one
  25419.                 BREAK
  25420.             end
  25421.  
  25422.         SET @slot_name=@process_name+convert(varchar,@i)
  25423.         
  25424.         --the call is not blocking, return immediately having acquired the lock or not
  25425.         exec @retcode=sp_getapplock @Resource=@slot_name,@LockMode=N'Exclusive',@LockOwner='Session',@LockTimeout=0
  25426.         IF (@retcode <> 0 AND @retcode <> -1)
  25427.             BEGIN
  25428.                 RAISERROR(21414,16,-1)
  25429.                 RETURN(@retcode)
  25430.             END
  25431.     
  25432.         IF (@retcode = 0)       -- got lock for that slot - cleanup and leave.
  25433.             BEGIN
  25434.                 -- Release the "Im first lock"
  25435.                 exec @retcode=sp_releaseapplock @process_name,@LockOwner=N'Session'
  25436.                 IF (@retcode <> 0)
  25437.                 BEGIN
  25438.                     SET @slot_name=NULL
  25439.                     RAISERROR(21415, 16, -1)
  25440.                     RETURN(@retcode)
  25441.                 END
  25442.                 select @lock_acquired = 1
  25443.             -- We got our slot and released the Im first lock.  We're done.
  25444.                 BREAK
  25445.             END
  25446.         ELSE
  25447.         IF (@retcode = -1)  -- Couldn't immediately get the lock.  So try the next one.
  25448.             BEGIN
  25449.             SET @i=@i+1
  25450.                 IF @i <= @concurrent_max
  25451.                     CONTINUE   -- restart the loop
  25452.                 ELSE
  25453.                     BEGIN        -- Sleep and start over.
  25454.                     if @return_immediately=1
  25455.                         begin
  25456.                             select @lock_acquired = 0 --slot name does not matter in this case
  25457.                             BREAK
  25458.                         end
  25459.                     else
  25460.                         begin
  25461.                             WAITFOR DELAY @delaytime
  25462.                             SET @i=1
  25463.                             CONTINUE   -- restart the loop
  25464.                         end
  25465.                     END
  25466.             END
  25467.         
  25468.     END
  25469.     
  25470.     --output the slot name for the purpose of releasing the lock by the caller
  25471.     --if the value if NULL, the caller does not acquire the lock
  25472.     select @lock_acquired, @slot_name
  25473. RETURN(0)
  25474.  
  25475. exec dbo.sp_MS_marksystemobject sp_MSacquireSlotLock
  25476. go
  25477.  
  25478. grant execute on dbo.sp_MSacquireSlotLock to public
  25479. go
  25480.  
  25481. -- this procedure is called by merge process to release slot lock
  25482. -- that is acquired by calling sp_MSacquireSlotLock.
  25483.  
  25484. raiserror('Creating procedure sp_MSreleaseSlotLock', 0,1)
  25485. GO
  25486.  
  25487. -- this stored procedure is called by merge agent to release the application lock
  25488. -- acquired by sp_MSacquireSlotLock
  25489.  
  25490. CREATE PROC sp_MSreleaseSlotLock
  25491. @process_name    sysname
  25492. AS
  25493. declare @retcode int
  25494.  
  25495. -- Security Checking 
  25496. -- sysadmin or db_owner or PAL user have access
  25497. if not exists (select * from dbo.sysmergepublications 
  25498.                     where 1 = {fn ISPALUSER(pubid)})
  25499. begin
  25500.     RAISERROR (15247, 11, -1)
  25501.     return (1)
  25502. end
  25503.  
  25504.  
  25505. exec @retcode=sp_releaseapplock @process_name,@LockOwner=N'Session'
  25506. IF (@retcode <> 0)
  25507.     BEGIN
  25508.         RAISERROR(21415, 16, -1)
  25509.         return (1)
  25510.     END
  25511. return @retcode
  25512. GO
  25513. exec dbo.sp_MS_marksystemobject sp_MSreleaseSlotLock 
  25514. go
  25515. grant exec on dbo.sp_MSreleaseSlotLock to public
  25516. go
  25517.  
  25518. raiserror('Creating procedure sp_MSrepl_check_server', 0,1)
  25519. go
  25520.  
  25521. CREATE PROCEDURE sp_MSrepl_check_server (
  25522.     @srvname sysname,
  25523.     @check_distdb bit = 0
  25524.         ) AS
  25525.     -- This sp is called by sp_dropserver to check if the server is in use by replication.
  25526.     declare @subscriber_bit smallint
  25527.     declare @distributor_bit smallint
  25528.     declare @retcode int
  25529.     declare @proc nvarchar(255)
  25530.     declare @dbname sysname
  25531.  
  25532.     -- Intialize
  25533.     select @distributor_bit = 8
  25534.     select @subscriber_bit = 4
  25535.  
  25536.     if @check_distdb = 0
  25537.     begin
  25538.         -- Check to see if the server is marked as a Distributor
  25539.         if exists (select * from sysservers where UPPER(srvname) = UPPER(@srvname) and
  25540.             srvstatus & @distributor_bit <> 0)
  25541.         begin
  25542.             raiserror(20581, 16, -1, @srvname) 
  25543.             return (1)
  25544.         end
  25545.         -- Check to see if the server is marked as a subscriber
  25546.         if exists (select * from sysservers where UPPER(srvname) = UPPER(@srvname) and
  25547.             srvstatus & @subscriber_bit <> 0)
  25548.         begin
  25549.             raiserror(20583, 16, -1, @srvname) 
  25550.             return (1)
  25551.         end
  25552.         -- Check to see if the server is a dist publisher
  25553.         if object_id('msdb.dbo.MSdistpublishers') is not null
  25554.         begin
  25555.             if exists (select * from msdb.dbo.MSdistpublishers where
  25556.                 UPPER(name) = UPPER(@srvname) collate database_default)
  25557.             begin
  25558.                 raiserror(20582, 16, -1, @srvname) 
  25559.                 return (1)
  25560.             end
  25561.         end
  25562.         -- Check to see if the server is in use as a subscriber in the distribution dbs.
  25563.         if object_id('msdb.dbo.MSdistributiondbs') is not null
  25564.         begin
  25565.             declare hCForEachDb CURSOR LOCAL FAST_FORWARD FOR 
  25566.                 select name from msdb.dbo.MSdistributiondbs
  25567.             FOR READ ONLY
  25568.             open hCForEachDb
  25569.             fetch hCForEachDb into @dbname
  25570.             /* Loop for each database */
  25571.             while (@@fetch_status >= 0) 
  25572.             begin
  25573.                 select @proc = quotename(@dbname) + '.dbo.sp_MSrepl_check_server'
  25574.                 exec @retcode = @proc
  25575.                     @srvname = @srvname,
  25576.                     @check_distdb = 1
  25577.                 if @retcode <> 0 or @@error <> 0
  25578.                     return (1)
  25579.                 fetch hCForEachDb into @dbname
  25580.             end /* while FETCH_SUCCESS */
  25581.         end
  25582.     end
  25583.     else
  25584.     begin
  25585.         if object_id('MSsubscriber_info') is not null
  25586.         begin
  25587.             declare @publisher sysname
  25588.             select @publisher =  publisher from MSsubscriber_info sub
  25589.                 where UPPER(subscriber) = UPPER(@srvname)
  25590.             if @publisher is not null
  25591.             begin
  25592.                 raiserror(20584, 16, -1, @srvname, @publisher) 
  25593.                 return (1)
  25594.             end
  25595.         end
  25596.     end
  25597.  
  25598. GO
  25599.  
  25600. EXEC dbo.sp_MS_marksystemobject sp_MSrepl_check_server
  25601. go
  25602.  
  25603. raiserror('Creating procedure sp_MSreset_synctran_bit', 0,1)
  25604. go
  25605. CREATE PROCEDURE sp_MSreset_synctran_bit (
  25606.     @owner          sysname,
  25607.     @table          sysname
  25608. )AS
  25609.     declare @qualified_name nvarchar(300)
  25610.     declare @synctran_bit int
  25611.  
  25612.     select @synctran_bit            = 256
  25613.     
  25614.     if @owner = N''
  25615.         select @qualified_name = @table
  25616.     else
  25617.         select @qualified_name = quotename(@owner) + '.' + quotename(@table) 
  25618.  
  25619.     -- Unmark synctran bit
  25620.     update sysobjects set replinfo = replinfo & ~@synctran_bit where 
  25621.         id = object_id(@qualified_name) and
  25622.         (replinfo & @synctran_bit) <> 0
  25623.     IF @@ERROR <> 0 
  25624.         return(1)
  25625.     return(0)
  25626. GO
  25627.  
  25628. EXEC dbo.sp_MS_marksystemobject sp_MSreset_synctran_bit
  25629. go
  25630.  
  25631. grant execute on dbo.sp_MSreset_synctran_bit to public
  25632. go
  25633.  
  25634. --
  25635. -- Name: sp_MSenum_replsqlqueues
  25636. --
  25637. -- Description: Proc that enumerates all the subscriber + subscriber_db for the currently 
  25638. -- active queued subscriptions in all the distribution databases in this system. Invoked on
  25639. -- Distributor for SQL based queues in Updating subscribers by Queue reader Agent
  25640. --
  25641. -- Parameter :
  25642. -- @curdistdb    sysname : specified distribution database. If NULL, then
  25643. --             enumerate the queues for all the distribution databases
  25644. --
  25645. -- Owner: KaushikC
  25646. --
  25647. -- Returns: 0 - succeeded
  25648. --          1 - failed
  25649. --
  25650. -- Resultset: 
  25651. --        publisher sysname collate database_default not null,
  25652. --        publisher_db sysname collate database_default not null,
  25653. --        subscriber sysname collate database_default not null,
  25654. --        subscriber_db sysname collate database_default not null,
  25655. --        publication sysname collate database_default not null,
  25656. --        dist_db sysname collate database_default not null
  25657. --
  25658. -- Security: Procedural security check is done inside this procedure
  25659. --           to make sure that the caller is either a member of the db_owner
  25660. --           role of the distribution database or a member of the sysadmin role
  25661. --
  25662. raiserror('Creating procedure sp_MSenum_replsqlqueues', 0,1)
  25663. go
  25664. create procedure sp_MSenum_replsqlqueues
  25665. (
  25666.     @curdistdb    sysname = NULL
  25667. )
  25668. as
  25669. begin
  25670.     declare @distbit int
  25671.     declare @db_name sysname
  25672.     declare @cmd nvarchar(1024)
  25673.  
  25674.     select @distbit = 16
  25675.     --
  25676.     -- security check
  25677.     --
  25678.     if (is_srvrolemember('sysadmin') != 1)
  25679.     begin
  25680.         --
  25681.         -- non SA user
  25682.         -- @curdistdb cannot be null for NON-SA user
  25683.         --
  25684.         if (@curdistdb is null)
  25685.         begin
  25686.             raiserror (14043, 16, -1, '@curdistdb')
  25687.             return 1
  25688.         end
  25689.         else
  25690.         begin
  25691.             --
  25692.             -- The user has to be DBO of the specified distribution db
  25693.             --
  25694.             declare @fisdbo bit
  25695.                     ,@securitycmd nvarchar(300)
  25696.  
  25697.             select @securitycmd = quotename(@curdistdb) + '.dbo.sp_executesql'
  25698.             exec @securitycmd
  25699.                 N'if is_member(N''db_owner'') = 1 set @fisdbo = 1'
  25700.                 ,N'@fisdbo bit output'
  25701.                 ,@fisdbo output 
  25702.             if (@fisdbo != 1)
  25703.             begin
  25704.                 raiserror (21050, 14, 3)
  25705.                 return 1
  25706.             end
  25707.         end
  25708.     end
  25709.     --
  25710.     -- create the temp table to store the relevant information
  25711.     --
  25712.     create table #replqueue (
  25713.         publisher sysname collate database_default not null,
  25714.         publisher_db sysname collate database_default not null,
  25715.         subscriber sysname collate database_default not null,
  25716.         subscriber_db sysname collate database_default not null,
  25717.         publication sysname collate database_default not null,
  25718.         dist_db sysname collate database_default not null
  25719.     )
  25720.     create unique index ucreplqueue ON #replqueue (subscriber, subscriber_db, publication)
  25721.  
  25722.     --
  25723.     -- Has the user specified a distribution database
  25724.     --
  25725.     if (@curdistdb is NULL)
  25726.     begin
  25727.         --
  25728.         -- Go through all the distribution databases
  25729.         --
  25730.         declare hCdatabase CURSOR LOCAL FAST_FORWARD FOR 
  25731.             select name from master.dbo.sysdatabases 
  25732.             where
  25733.                 category & @distbit <> 0 and
  25734.                 has_dbaccess(name) = 1
  25735.             for read only
  25736.     end
  25737.     else
  25738.     begin
  25739.         --
  25740.         -- User specified Distribution Database
  25741.         -- Validate the user specified name
  25742.         --
  25743.         if exists (select name from master.dbo.sysdatabases 
  25744.         where
  25745.             name = @curdistdb and
  25746.             category & @distbit <> 0 and
  25747.             has_dbaccess(name) = 1)
  25748.         begin
  25749.             declare hCdatabase CURSOR LOCAL FAST_FORWARD FOR
  25750.             select @curdistdb
  25751.             for read only
  25752.         end
  25753.         else
  25754.         begin
  25755.             --
  25756.             -- Error : Invalid distribution db specified
  25757.             --
  25758.             raiserror(20587, 16, 3, N'@curdistdb', N'sp_MSenum_replsqlqueues')
  25759.             return 1
  25760.         end
  25761.     end
  25762.     
  25763.     --
  25764.     -- Enumerate
  25765.     --
  25766.     open hCdatabase
  25767.     fetch next from hCdatabase into @db_name
  25768.     while (@@fetch_status <> -1)
  25769.     begin
  25770.         select @cmd =
  25771.         'SET NOCOUNT ON ' +
  25772.         'INSERT INTO #replqueue (publisher, publisher_db, subscriber, subscriber_db, publication, dist_db) ' +
  25773.         'SELECT c.srvname, a.publisher_db, b.srvname, a.subscriber_db, a.publication, N''' + @db_name + ''' ' +
  25774.         'FROM ' + QUOTENAME(@db_name) + '.dbo.MSdistribution_agents as a ' +
  25775.             'JOIN master.dbo.sysservers as b ' +
  25776.             'ON a.subscriber_id = b.srvid ' +
  25777.             'JOIN master.dbo.sysservers as c ' + 
  25778.             'ON a.publisher_id = c.srvid ' + 
  25779.             'WHERE substring(queue_id, 1, 10) = N''mssqlqueue'' '
  25780.             
  25781.         exec (@cmd)
  25782.         fetch next from hCdatabase into @db_name
  25783.     end
  25784.     close hCdatabase
  25785.     deallocate hCdatabase
  25786.  
  25787.     --
  25788.     -- select the contents of the temp table
  25789.     --
  25790.     select * from #replqueue
  25791.  
  25792.     --
  25793.     -- cleanup
  25794.     --
  25795.     drop table #replqueue
  25796. end
  25797. go
  25798.  
  25799. EXEC dbo.sp_MS_marksystemobject sp_MSenum_replsqlqueues
  25800. go
  25801.  
  25802. --
  25803. -- Name: sp_MSenum_replqueues
  25804. --
  25805. -- Description: Proc that enumerates all the all the MSMQ based queues that 
  25806. -- are currently active in the specified distribution database. Invoked on
  25807. -- Distributor for SQL based queues in Updating subscribers by Queue reader Agent
  25808. --
  25809. -- Owner: KaushikC
  25810. --
  25811. -- Parameter :
  25812. -- @curdistdb    sysname : specified distribution database. If NULL, then
  25813. --             enumerate the queues for all the distribution databases
  25814. --
  25815. -- Returns: 0 - succeeded
  25816. --          1 - failed
  25817. --
  25818. -- Resultset: 
  25819. --        queue_server sysname collate database_default not null,
  25820. --        queue_id sysname collate database_default not null,
  25821. --        dist_db sysname collate database_default not null
  25822. --
  25823. -- Security: Procedural security check is done inside this procedure
  25824. --           to make sure that the caller is either a member of the db_owner
  25825. --           role of the distribution database or a member of the sysadmin role
  25826. --
  25827. raiserror('Creating procedure sp_MSenum_replqueues', 0,1)
  25828. go
  25829. create procedure sp_MSenum_replqueues
  25830. (
  25831.     @curdistdb    sysname = NULL
  25832. )
  25833. as
  25834. begin
  25835.     declare @distbit int
  25836.     declare @db_name sysname
  25837.     declare @cmd nvarchar(1024)
  25838.  
  25839.     select @distbit = 16
  25840.     --
  25841.     -- security check
  25842.     --
  25843.     if (is_srvrolemember('sysadmin') != 1)
  25844.     begin
  25845.         --
  25846.         -- non SA user
  25847.         -- @curdistdb cannot be null for NON-SA user
  25848.         --
  25849.         if (@curdistdb is null)
  25850.         begin
  25851.             raiserror (14043, 16, -1, '@curdistdb')
  25852.             return 1
  25853.         end
  25854.         else
  25855.         begin
  25856.             --
  25857.             -- The user has to be DBO of the specified distribution db
  25858.             --
  25859.             declare @fisdbo bit
  25860.                     ,@securitycmd nvarchar(300)
  25861.  
  25862.             select @securitycmd = quotename(@curdistdb) + '.dbo.sp_executesql'
  25863.             exec @securitycmd
  25864.                 N'if is_member(N''db_owner'') = 1 set @fisdbo = 1'
  25865.                 ,N'@fisdbo bit output'
  25866.                 ,@fisdbo output 
  25867.             if (@fisdbo != 1)
  25868.             begin
  25869.                 raiserror (21050, 14, 3)
  25870.                 return 1
  25871.             end
  25872.         end
  25873.     end
  25874.     --
  25875.     -- create the temp table to store the relevant information
  25876.     --
  25877.     create table #replqueue (
  25878.         queue_server sysname collate database_default not null,
  25879.         queue_id sysname collate database_default not null,
  25880.         dist_db sysname collate database_default not null
  25881.     )
  25882.     create unique clustered index ucreplqueue ON #replqueue (queue_id)
  25883.  
  25884.     --
  25885.     -- Has the user specified a distribution database
  25886.     --
  25887.     if (@curdistdb is NULL)
  25888.     begin
  25889.         --
  25890.         -- Go through all the distribution databases
  25891.         --
  25892.         declare hCdatabase CURSOR LOCAL FAST_FORWARD FOR 
  25893.             select name from master.dbo.sysdatabases 
  25894.             where
  25895.                 category & @distbit <> 0 and
  25896.                 has_dbaccess(name) = 1
  25897.             for read only
  25898.     end
  25899.     else
  25900.     begin
  25901.         --
  25902.         -- User specified Distribution Database
  25903.         -- Validate the user specified name
  25904.         --
  25905.         if exists (select name from master.dbo.sysdatabases 
  25906.         where
  25907.             name = @curdistdb and
  25908.             category & @distbit <> 0 and
  25909.             has_dbaccess(name) = 1)
  25910.         begin
  25911.             declare hCdatabase CURSOR LOCAL FAST_FORWARD FOR
  25912.             select @curdistdb
  25913.             for read only
  25914.         end
  25915.         else
  25916.         begin
  25917.             --
  25918.             -- Error : Invalid distribution db specified
  25919.             --
  25920.             raiserror(20587, 16, 4, N'@curdistdb', N'sp_MSenum_replqueues')
  25921.             return 1
  25922.         end
  25923.     end
  25924.  
  25925.     --
  25926.     -- Enumerate
  25927.     --
  25928.     open hCdatabase
  25929.     fetch next from hCdatabase into @db_name
  25930.     while (@@fetch_status <> -1)
  25931.     begin
  25932.         select @cmd =
  25933.         'SET NOCOUNT ON ' +
  25934.         'INSERT INTO #replqueue (queue_server, queue_id, dist_db) ' +
  25935.         'SELECT queue_server, queue_id, ' +
  25936.                 'N''' + replace(@db_name, '''', '''''') + ''' ' +
  25937.         'FROM ' +
  25938.                 QUOTENAME(@db_name) + '.dbo.MSdistribution_agents ' +
  25939.         'WHERE ' +
  25940.                 'queue_id IS NOT NULL and substring(queue_id, 1, 10) != N''mssqlqueue'''
  25941.             
  25942.         exec (@cmd)
  25943.         fetch next from hCdatabase into @db_name
  25944.     end
  25945.     close hCdatabase
  25946.     deallocate hCdatabase
  25947.  
  25948.     --
  25949.     -- select the contents of the temp table to present
  25950.     -- the formatted queue name
  25951.     --
  25952.     select     N'DIRECT=OS:' + queue_server + N'\PRIVATE$\' + queue_id AS 'queue_format'
  25953.             ,dist_db
  25954.     from #replqueue
  25955.     
  25956.     --
  25957.     -- cleanup
  25958.     --
  25959.     drop table #replqueue
  25960. end
  25961. go
  25962.  
  25963. EXEC dbo.sp_MS_marksystemobject sp_MSenum_replqueues
  25964. go
  25965.  
  25966. raiserror('Creating procedure sp_browsemergesnapshotfolder', 0,1)
  25967. go
  25968. CREATE PROCEDURE sp_browsemergesnapshotfolder (
  25969.     @publication sysname
  25970.     )
  25971. AS
  25972. BEGIN
  25973.     SET NOCOUNT ON
  25974.     DECLARE @dbname sysname
  25975.     DECLARE @alt_directory_type INT
  25976.     DECLARE @directory_type INT
  25977.     SELECT @alt_directory_type = 25
  25978.     SELECT @directory_type = 7
  25979.  
  25980.     if (1 <> is_member('db_owner'))
  25981.     begin    
  25982.         RAISERROR (15247, 11, -1)
  25983.         return (1)
  25984.     end
  25985.  
  25986.     IF (EXISTS (SELECT * FROM sysobjects WHERE name = N'sysmergepublications')) AND
  25987.        (EXISTS (SELECT * FROM sysobjects WHERE name = N'sysmergeschemachange'))
  25988.     BEGIN
  25989.         SELECT 'snapshot_folder' = schematext 
  25990.           FROM sysmergeschemachange sc 
  25991.     INNER JOIN sysmergepublications mp
  25992.             ON sc.pubid = mp.pubid
  25993.          WHERE mp.name = @publication
  25994.            AND upper(mp.publisher) = upper(@@servername)
  25995.            AND publisher_db = db_name()  
  25996.            AND (schematype = @directory_type OR schematype = @alt_directory_type)
  25997.       ORDER BY schematype desc
  25998.     END  
  25999.     ELSE
  26000.     BEGIN
  26001.         SELECT @dbname = DB_NAME()
  26002.         RAISERROR(21147, 16, -1, @dbname)
  26003.         RETURN 1
  26004.     END
  26005. END
  26006. GO
  26007. EXEC dbo.sp_MS_marksystemobject sp_browsemergesnapshotfolder
  26008. go
  26009.  
  26010. raiserror('Creating procedure sp_browsesnapshotfolder', 0,1)
  26011. go
  26012. CREATE PROCEDURE sp_browsesnapshotfolder (
  26013.     @publication    sysname,
  26014.     @subscriber     sysname = NULL,
  26015.     @subscriber_db  sysname = NULL
  26016.     )
  26017. AS
  26018. BEGIN
  26019.     SET NOCOUNT ON
  26020.     DECLARE @retcode        INT
  26021.     DECLARE @publisher      sysname
  26022.     DECLARE @publisher_db   sysname
  26023.     DECLARE @distributor    sysname
  26024.     DECLARE @distributiondb sysname
  26025.     DECLARE @distproc       nvarchar(300)
  26026.     DECLARE @article_id     INT
  26027.     
  26028.     SELECT @retcode = 0
  26029.     SELECT @publisher = NULL
  26030.     SELECT @publisher_db = DB_NAME()
  26031.     SELECT @distributor = NULL
  26032.     SELECT @distributiondb = NULL
  26033.     SELECT @article_id = NULL
  26034.     
  26035.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  26036.     IF @@ERROR <> 0 or @retcode <> 0
  26037.         return (1)
  26038.  
  26039.     -- Either both of @subscriber and @subscriber_db are NULL or
  26040.     -- both of them have to be non-null
  26041.     IF ((@subscriber IS NULL OR @subscriber = N'') 
  26042.         AND @subscriber_db IS NOT NULL AND @subscriber_db <> N'') OR
  26043.        ((@subscriber_db IS NULL OR @subscriber_db = N'') 
  26044.         AND @subscriber IS NOT NULL AND @subscriber <> N'')
  26045.     BEGIN
  26046.         RAISERROR(21148, 16, -1)
  26047.     END
  26048.     
  26049.     IF EXISTS (SELECT * FROM sysobjects WHERE name = N'syspublications') AND
  26050.        EXISTS (SELECT * FROM sysobjects WHERE name = N'sysextendedarticlesview')
  26051.     BEGIN    
  26052.         SELECT @publisher = @@SERVERNAME
  26053.     
  26054.         -- Get the smallest article id for the publication since 
  26055.         -- method for identifying a publication is not readily available 
  26056.         -- on the distributor
  26057.  
  26058.         SELECT @article_id = MIN(artid) 
  26059.           FROM sysextendedarticlesview sa
  26060.     INNER JOIN syspublications sp
  26061.             ON sa.pubid = sp.pubid
  26062.          WHERE sp.name = @publication
  26063.  
  26064.         IF @article_id IS NULL
  26065.         BEGIN
  26066.             RAISERROR(20026, 16, -1, @publication)
  26067.         END         
  26068.  
  26069.         EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  26070.                                                @distribdb = @distributiondb OUTPUT
  26071.         IF @retcode <> 0
  26072.             RETURN @retcode
  26073.     
  26074.         SELECT @distributor = RTRIM(@distributor)
  26075.     
  26076.         IF LOWER(@@SERVERNAME) <> LOWER(@distributor)
  26077.         BEGIN
  26078.             SELECT @distproc = @distributor + '.' + @distributiondb + 
  26079.                                '.dbo.sp_MSbrowsesnapshotfolder'
  26080.         END
  26081.         ELSE
  26082.         BEGIN
  26083.             SELECT @distproc = @distributiondb + '.dbo.sp_MSbrowsesnapshotfolder'
  26084.         END
  26085.         EXECUTE @retcode = @distproc
  26086.                     @publisher = @publisher, 
  26087.                     @publisher_db = @publisher_db,
  26088.                     @article_id = @article_id,
  26089.                     @subscriber = @subscriber,
  26090.                     @subscriber_db = @subscriber_db
  26091.         RETURN @retcode
  26092.     END
  26093.     ELSE
  26094.     BEGIN
  26095.         RAISERROR(21149, 16, -1, @publisher_db)
  26096.         RETURN 1
  26097.     END
  26098. END
  26099. GO
  26100. EXEC dbo.sp_MS_marksystemobject sp_browsesnapshotfolder
  26101. go
  26102.  
  26103. raiserror('Creating procedure sp_MScopysnapshot', 0,1)
  26104. go
  26105. CREATE PROCEDURE sp_MScopysnapshot (
  26106.     @source_folder           nvarchar(255),
  26107.     @destination_folder      nvarchar(255)
  26108.     )
  26109. AS
  26110. BEGIN
  26111.     SET NOCOUNT ON
  26112.     DECLARE @directory_exists bit    
  26113.     DECLARE @ftporuncdir      nvarchar(5)
  26114.     DECLARE @pubdir           nvarchar(255)
  26115.     DECLARE @timestampdir     nvarchar(255)
  26116.     DECLARE @bslashindex      int
  26117.     DECLARE @bslashindex2     int
  26118.     DECLARE @bslashcounter    int
  26119.     DECLARE @command          nvarchar(1000)
  26120.     DECLARE @retcode          int
  26121.     DECLARE @platform_nt      bit
  26122.  
  26123.     IF platform() & 0x1 = 0x1
  26124.         SELECT @platform_nt = 1
  26125.     ELSE
  26126.         SELECT @platform_nt = 0
  26127.  
  26128.     -- If @source_folder is NULL then either the snapshot has not been 
  26129.     -- generated or it has been cleaned up
  26130.     IF @source_folder IS NULL OR @source_folder = N''
  26131.     BEGIN
  26132.         RAISERROR(21289, 16, -1)
  26133.         RETURN (1)
  26134.     END
  26135.  
  26136.     -- Make sure that the @destination folder is not null
  26137.     IF @destination_folder IS NULL OR
  26138.        @destination_folder = N''
  26139.     BEGIN
  26140.         RAISERROR(21287, 16, -1)      
  26141.         RETURN (1)
  26142.     END
  26143.  
  26144.     -- Append backslash to @destination_folder if it is not 
  26145.     -- there already
  26146.     IF SUBSTRING(@destination_folder, LEN(@destination_folder), 1) <> N'\'
  26147.     BEGIN
  26148.         SELECT @destination_folder = @destination_folder + N'\'
  26149.     END
  26150.  
  26151.     -- Check if the destination folder exists 
  26152.     EXEC sp_MSget_file_existence @destination_folder, @directory_exists OUTPUT
  26153.     IF @directory_exists = 0
  26154.     BEGIN
  26155.         RAISERROR(21287, 16, -1)      
  26156.         RETURN (1)
  26157.     END    
  26158.     
  26159.     -- Parse out the last three components in the source folder 
  26160.     -- Note that the source_folder must have a trailing backslash
  26161.     SELECT @bslashindex = 1
  26162.     SELECT @bslashindex2 = 1
  26163.     SELECT @bslashcounter = 0
  26164.     WHILE (@bslashindex <> 0)
  26165.     BEGIN
  26166.         SELECT @bslashindex = CHARINDEX(N'\', @source_folder, @bslashindex + 1)
  26167.         SELECT @bslashcounter = @bslashcounter + 1
  26168.         IF @bslashcounter > 4
  26169.         BEGIN
  26170.             SELECT @bslashindex2 = CHARINDEX(N'\', @source_folder, @bslashindex2 + 1)
  26171.         END    
  26172.     END  
  26173.  
  26174.     SELECT @bslashindex = CHARINDEX(N'\', @source_folder, @bslashindex2 + 1)
  26175.     SELECT @ftporuncdir = SUBSTRING(@source_folder, @bslashindex2 + 1, @bslashindex - @bslashindex2 - 1)
  26176.     SELECT @bslashindex2 = @bslashindex
  26177.  
  26178.     SELECT @bslashindex = CHARINDEX(N'\', @source_folder, @bslashindex2 + 1)
  26179.     SELECT @pubdir = SUBSTRING(@source_folder, @bslashindex2 + 1, @bslashindex - @bslashindex2 - 1) 
  26180.     SELECT @bslashindex2 = @bslashindex
  26181.  
  26182.     SELECT @bslashindex = CHARINDEX(N'\', @source_folder, @bslashindex2 + 1)
  26183.     SELECT @timestampdir = SUBSTRING(@source_folder, @bslashindex2 + 1, @bslashindex - @bslashindex2 - 1) 
  26184.     SELECT @bslashindex2 = @bslashindex
  26185.         
  26186.     -- Create the subdirectory structure underneath the specified snapshot
  26187.     -- folder. Ignore errors for now, we will check whether the directory 
  26188.     -- is successfully created later on.
  26189.  
  26190.     -- Don't suppress output from xp_cmdshell so user knows what's going on
  26191.     -- in case something goes wrong 
  26192.     SELECT @destination_folder = @destination_folder + @ftporuncdir + '\'
  26193.     SELECT @command = 'mkdir "' + fn_escapecmdshellsymbolsremovequotes(@destination_folder) collate database_default + '"'
  26194.     IF (@platform_nt = 1)
  26195.         SELECT @command = '" ' + @command + ' "'
  26196.     EXEC master..xp_cmdshell @command
  26197.     
  26198.     SELECT @destination_folder = @destination_folder + @pubdir + '\'
  26199.     SELECT @command = 'mkdir "' + fn_escapecmdshellsymbolsremovequotes(@destination_folder) collate  database_default + '"'
  26200.     IF (@platform_nt = 1)
  26201.         SELECT @command = '" ' + @command + ' "'
  26202.     EXEC master..xp_cmdshell @command
  26203.  
  26204.     SELECT @destination_folder = @destination_folder + @timestampdir + '\'
  26205.     SELECT @command = 'mkdir "' + fn_escapecmdshellsymbolsremovequotes(@destination_folder) collate database_default + '"'
  26206.     IF (@platform_nt = 1)
  26207.         SELECT @command = '" ' + @command + ' "'
  26208.     EXEC master..xp_cmdshell @command
  26209.  
  26210.     -- Check if the real destination folder exists
  26211.     EXEC sp_MSget_file_existence @destination_folder, @directory_exists OUTPUT
  26212.     IF @directory_exists = 0
  26213.     BEGIN
  26214.         RAISERROR(21288, 16, -1)
  26215.         RETURN (1)
  26216.     END
  26217.  
  26218.     -- Do the actual copying
  26219.     SELECT @command = 'copy "' + fn_escapecmdshellsymbolsremovequotes(@source_folder) collate database_default + '*.*" "' + fn_escapecmdshellsymbolsremovequotes(@destination_folder) collate database_default + '"'    
  26220.     IF (@platform_nt = 1)
  26221.         SELECT @command = '" ' + @command + ' "'
  26222.     
  26223.     EXEC @retcode = master..xp_cmdshell @command
  26224.     
  26225.     IF @retcode <> 0
  26226.         RETURN (1)
  26227.     ELSE
  26228.         RETURN (0)
  26229. END
  26230. go
  26231. EXEC dbo.sp_MS_marksystemobject sp_MScopysnapshot
  26232. go
  26233.  
  26234. raiserror('Creating procedure sp_copymergesnapshot', 0,1)
  26235. go
  26236. CREATE PROCEDURE sp_copymergesnapshot (
  26237.     @publication          sysname,
  26238.     @destination_folder   nvarchar(255)
  26239.     )
  26240. AS
  26241. BEGIN
  26242.     SET NOCOUNT ON
  26243.     DECLARE @retcode       int
  26244.     DECLARE @source_folder nvarchar(255)
  26245.     SELECT @retcode = 0
  26246.     
  26247.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  26248.     IF @@ERROR <> 0 OR @retcode <> 0
  26249.         RETURN (1)
  26250.  
  26251.     CREATE TABLE #snapshot_folders
  26252.     (
  26253.         id              int identity, 
  26254.         snapshot_folder nvarchar(255) collate database_default
  26255.     )
  26256.     IF @@ERROR <> 0
  26257.     BEGIN
  26258.         RETURN 1
  26259.     END
  26260.  
  26261.     INSERT INTO #snapshot_folders
  26262.     EXEC @retcode = sp_browsemergesnapshotfolder @publication = @publication
  26263.     IF @retcode <> 0 OR @@ERROR <> 0
  26264.     BEGIN
  26265.         GOTO Failure
  26266.     END
  26267.     
  26268.     SELECT @source_folder = (select top 1 snapshot_folder FROM #snapshot_folders ORDER BY id ASC)
  26269.     IF @@ERROR <> 0
  26270.     BEGIN
  26271.         GOTO Failure
  26272.     END        
  26273.     SET ROWCOUNT 0    
  26274.  
  26275.     EXEC @retcode = sp_MScopysnapshot @source_folder,
  26276.                                       @destination_folder
  26277.     IF @retcode <> 0 OR @@ERROR <> 0 
  26278.     BEGIN
  26279.         GOTO Failure
  26280.     END
  26281.  
  26282.     DROP TABLE #snapshot_folders
  26283.     RETURN 0
  26284. Failure:
  26285.     SET ROWCOUNT 0    
  26286.     DROP TABLE #snapshot_folders        
  26287.     RETURN 1
  26288. END
  26289. GO
  26290. EXEC dbo.sp_MS_marksystemobject sp_copymergesnapshot
  26291. go
  26292.  
  26293. raiserror('Creating procedure sp_copysnapshot', 0,1)
  26294. go
  26295. CREATE PROCEDURE sp_copysnapshot (
  26296.     @publication        sysname,
  26297.     @destination_folder nvarchar(255),
  26298.     @subscriber         sysname = NULL,
  26299.     @subscriber_db      sysname = NULL
  26300.     )
  26301. AS
  26302. BEGIN
  26303.     SET NOCOUNT ON
  26304.     DECLARE @retcode       int
  26305.     DECLARE @source_folder nvarchar(255)
  26306.     SELECT @retcode = 0
  26307.     
  26308.     -- security check, db_owner
  26309.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  26310.     IF @@ERROR <> 0 or @retcode <> 0
  26311.         return (1)
  26312.  
  26313.     CREATE TABLE #snapshot_folders
  26314.     (
  26315.         id              int identity,
  26316.         snapshot_folder nvarchar(255) collate database_default
  26317.     )
  26318.     IF @@ERROR <> 0
  26319.     BEGIN
  26320.         RETURN 1
  26321.     END
  26322.  
  26323.     INSERT INTO #snapshot_folders
  26324.     EXEC @retcode = sp_browsesnapshotfolder @publication = @publication,
  26325.                                             @subscriber = @subscriber,
  26326.                                             @subscriber_db = @subscriber_db
  26327.     IF @retcode <> 0 OR @@ERROR <> 0
  26328.     BEGIN
  26329.         GOTO Failure
  26330.     END
  26331.  
  26332.     SELECT @source_folder = (select top 1 snapshot_folder FROM #snapshot_folders ORDER BY id)
  26333.     IF @@ERROR <> 0
  26334.     BEGIN
  26335.         GOTO Failure
  26336.     END        
  26337.     SET ROWCOUNT 0
  26338.  
  26339.     EXEC @retcode = sp_MScopysnapshot @source_folder,
  26340.                                       @destination_folder
  26341.     IF @retcode <> 0 OR @@ERROR <> 0 
  26342.     BEGIN
  26343.         GOTO Failure
  26344.     END
  26345.  
  26346.     DROP TABLE #snapshot_folders
  26347.     RETURN 0
  26348. Failure:
  26349.     SET ROWCOUNT 0
  26350.     DROP TABLE #snapshot_folders        
  26351.     RETURN 1
  26352. END
  26353. GO
  26354. EXEC dbo.sp_MS_marksystemobject sp_copysnapshot
  26355. go
  26356.  
  26357. raiserror('Creating procedure sp_MSrepl_validate_dts_package', 0,1)
  26358. go
  26359. CREATE PROCEDURE sp_MSrepl_validate_dts_package (
  26360.     @name sysname
  26361.      ) AS
  26362.  
  26363.     SET NOCOUNT ON
  26364.  
  26365.     /*
  26366.     ** Declarations.
  26367.     */
  26368.     if not exists (select * from msdb.dbo.sysdtspackages where
  26369.         name = @name)
  26370.     begin
  26371.         raiserror(21171, 
  26372.             16, -1, @name, @@servername )
  26373.         return 1
  26374.     end
  26375. go
  26376. EXEC dbo.sp_MS_marksystemobject sp_MSrepl_validate_dts_package
  26377. go
  26378.  
  26379. grant execute on dbo.sp_browsemergesnapshotfolder to public
  26380. go
  26381.  
  26382. grant execute on dbo.sp_browsesnapshotfolder to public
  26383. go
  26384.  
  26385. grant execute on dbo.sp_copymergesnapshot to public
  26386. go
  26387.  
  26388. grant execute on dbo.sp_copysnapshot to public
  26389. go
  26390.  
  26391. grant execute on dbo.sp_MSenum_replsqlqueues to public
  26392. grant execute on dbo.sp_MSenum_replqueues to public
  26393. go
  26394.  
  26395. raiserror('Creating procedure sp_MSget_load_hint', 0,1)
  26396. go
  26397. create procedure sp_MSget_load_hint @objname sysname, @type int
  26398. as
  26399. declare @objid int
  26400. declare @tabname sysname
  26401. declare @tabid int
  26402. declare @hint   nvarchar(2048)
  26403. declare @i int
  26404. declare @thiskey sysname
  26405. declare @indid smallint
  26406. declare @indstat int
  26407.  
  26408. select @objid = object_id( @objname )
  26409.  
  26410. if exists ( select * from sysobjects where id = @objid and type = 'V' )
  26411. begin
  26412.     select @tabid = depid from sysdepends where id = object_id( @objname )
  26413.     select @tabname = object_name( @tabid )
  26414.     
  26415.     select @indid = indid, @indstat = status 
  26416.         from sysindexes where id = @tabid and ( status & @type ) = @type
  26417.     if @indid is not null
  26418.     begin
  26419.         create table #colnames ( idxcolname sysname collate database_default)
  26420.  
  26421.         select @thiskey = index_col( @tabname, @indid, 1 )
  26422.         select @i = 2
  26423.         while (@thiskey is not null )
  26424.         begin
  26425.             insert into #colnames( idxcolname ) values( @thiskey )
  26426.             select @thiskey = index_col(@tabname, @indid, @i)
  26427.             select @i = @i + 1
  26428.         end
  26429.         if exists ( select idxcolname from #colnames 
  26430.                      where idxcolname not in
  26431.                         (select name from syscolumns where id = object_id( @objname ) ) )
  26432.         begin
  26433.             select @tabid = 0
  26434.         end    
  26435.         drop table #colnames
  26436.     end
  26437.     else
  26438.     begin
  26439.         select @tabid = 0
  26440.     end
  26441. end
  26442. else 
  26443. begin
  26444.     select @tabname = @objname
  26445.     select @tabid = object_id( @objname )
  26446.  
  26447.     select @indid = indid, @indstat = status 
  26448.         from sysindexes where id = @tabid and ( status & @type ) = @type
  26449.     if @indid is null
  26450.     begin
  26451.         select @tabid = 0
  26452.     end
  26453. end
  26454.  
  26455. -- Check for computed columns in chosen index. If computed columns exist,
  26456. -- don't return a load hint.
  26457. if @indid is not null
  26458. begin
  26459.     select @i = 1
  26460.     select @thiskey = index_col( @tabname, @indid, @i )
  26461.     while @thiskey is not null
  26462.     begin
  26463.         if isnull( columnproperty( @tabid, @thiskey, 'IsComputed' ), 0 ) = 1
  26464.         begin
  26465.             select @indid = null,
  26466.                    @tabid = 0
  26467.             break
  26468.         end
  26469.         select @i = @i + 1
  26470.         select @thiskey = index_col( @tabname, @indid, @i )
  26471.     end
  26472. end
  26473.  
  26474. if @tabid <> 0
  26475. begin
  26476.     select @hint = 'ORDER( '+QUOTENAME(index_col( @tabname, @indid, 1 )) collate database_default
  26477.     select @thiskey = index_col( @tabname, @indid, 2 ) 
  26478.     select @i = 3
  26479.     while (@thiskey is not null )
  26480.     begin
  26481.         select @hint = @hint + ',' + QUOTENAME(@thiskey) collate database_default
  26482.         select @thiskey = index_col(@tabname, @indid, @i)
  26483.         select @i = @i + 1
  26484.     end
  26485.  
  26486.     select @hint = @hint + ' ASC)'
  26487.  
  26488.     select @hint, @indstat
  26489. end
  26490. GO
  26491.  
  26492. EXEC dbo.sp_MS_marksystemobject sp_MSget_load_hint
  26493. go
  26494.  
  26495. grant execute on dbo.sp_MSget_load_hint to public
  26496. go
  26497.  
  26498. raiserror('Creating procedure sp_getsubscriptiondtspackagename', 0,1)
  26499. go
  26500. CREATE PROCEDURE sp_getsubscriptiondtspackagename (
  26501.     @publication sysname,
  26502.     @subscriber sysname = NULL
  26503.      ) AS
  26504.  
  26505.     SET NOCOUNT ON
  26506.  
  26507.     declare @name sysname
  26508.     declare @name_full sysname
  26509.     declare @id    int
  26510.     
  26511.     select @id = 1
  26512.     select @name = @publication
  26513.     if @subscriber is not null
  26514.         select @name = @name + N'_' + @subscriber
  26515.  
  26516.     -- reserver space for numbers to make the name unique
  26517.     select @name = substring(@name, 1, 100)
  26518.     select @name_full = @name
  26519.  
  26520.     while (1=1)
  26521.     begin
  26522.         if not exists (select * from msdb.dbo.sysdtspackages where
  26523.             name = @name_full)
  26524.             break
  26525.         select @name_full = @name + '_' + convert(nvarchar(10), @id)
  26526.         select @id = @id + 1
  26527.     end
  26528.     select N'new_package_name' = @name_full
  26529. go
  26530.  
  26531. EXEC dbo.sp_MS_marksystemobject sp_getsubscriptiondtspackagename
  26532. go
  26533.  
  26534. grant execute on dbo.sp_getsubscriptiondtspackagename to public
  26535. go
  26536.  
  26537. raiserror('Creating procedure sp_MSverifytranfilter', 0, 1)
  26538. GO
  26539. create procedure sp_MSverifytranfilter @objid int
  26540. as
  26541. DECLARE @artname sysname
  26542. DECLARE @sync_objid int
  26543. DECLARE @qual_sync_object nvarchar(1024)
  26544.  
  26545. DECLARE #testcursor CURSOR LOCAL FAST_FORWARD for
  26546.     SELECT name, sync_objid from sysarticles
  26547.     WHERE  objid = @objid
  26548.     
  26549. open #testcursor
  26550. fetch #testcursor into @artname, @sync_objid
  26551. while @@fetch_status <> -1
  26552. begin
  26553.     select @qual_sync_object = quotename( user_name(objectproperty(@sync_objid,'OwnerId'))) collate database_default + N'.' + quotename(object_name(@sync_objid)) collate database_default
  26554.  
  26555.     exec ( N'declare @var int select @var = count(*) from '+ @qual_sync_object + N' where 0 = 1' )
  26556.  
  26557.     if @@ERROR<> 0
  26558.     BEGIN
  26559.         raiserror( 14090, 16, -1, @artname )
  26560.         return 1
  26561.     END
  26562.     fetch #testcursor into @artname, @sync_objid
  26563. end
  26564. close #testcursor
  26565. deallocate #testcursor
  26566. return 0
  26567. GO
  26568.  
  26569. EXEC dbo.sp_MS_marksystemobject sp_MSverifytranfilter
  26570. go
  26571.  
  26572.  
  26573. raiserror('Creating procedure sp_repldropcolumn', 0,1)
  26574. GO
  26575.  
  26576. CREATE PROCEDURE sp_repldropcolumn(
  26577.     @source_object      nvarchar(270),
  26578.     @column                sysname,
  26579.     @from_agent            int = 0, 
  26580.     @schema_change_script nvarchar(4000) = NULL,
  26581.     @force_invalidate_snapshot bit = 1,    /* Force invalidate existing snapshot */
  26582.     @force_reinit_subscription bit = 0    /* Force reinit subscription */
  26583.  
  26584.     )
  26585. as
  26586.  
  26587. set nocount on
  26588. declare @objid            int
  26589. declare @at_publisher    bit
  26590. declare @pubname        sysname
  26591. declare @artname        sysname
  26592. declare @tran_pubname    sysname
  26593. declare @tran_artname    sysname
  26594. declare @tran_artid        int
  26595. declare @tran_pubid        int
  26596. declare @colid            int
  26597. declare @missing_index    int
  26598. declare @tablename        sysname
  26599. declare @pubid            uniqueidentifier
  26600. declare @artid            uniqueidentifier
  26601. declare @partitioned    int
  26602. declare @missing_count    int
  26603. declare @missing_bm        varbinary(32)
  26604. declare @old_missing_bm    varbinary(32)
  26605. declare @schematext        nvarchar(4000)
  26606. declare @schemaversion    int
  26607. declare @not_for_merge    bit
  26608. declare @qual_source_object nvarchar(262)
  26609. declare @qual_dest_object nvarchar(262)
  26610. declare @schematype        int
  26611. declare @schemaguid        uniqueidentifier
  26612. declare @conflict_table    sysname
  26613. declare @ins_conflict_proc sysname
  26614. declare @publisher        sysname
  26615. declare @publisher_db    sysname
  26616. declare @command        nvarchar(3000)
  26617. declare @sync_objid        int
  26618. declare @retcode         int
  26619. declare @snapshot_ready int
  26620. declare @con_id            int
  26621. declare @dest_owner        sysname
  26622. declare @dest_object    nvarchar(386)
  26623. declare @owner            sysname
  26624. declare @columnbm        varbinary(128)
  26625. declare @in_partition    int
  26626. declare @merge_pub_object_bit    int
  26627. declare @is_for_merge    bit
  26628. declare @is_for_tran    bit
  26629. declare @no_schema_replication bit
  26630. declare @servername        sysname
  26631. declare @dbname            sysname
  26632. declare @con_name        sysname
  26633. declare @v_unique_index    int
  26634. declare @qual_column        nvarchar(140)
  26635. declare @indid                int
  26636. declare @index_cnt             int
  26637. declare @pkkey                sysname
  26638. declare @v_unique_constraint    int
  26639. declare @merge_pub_unmarkcolumn_bit    int
  26640. declare @merge_pub_markcolumn_bit    int
  26641. declare @schema_start_lsn binary(10)
  26642. declare @schema_end_lsn binary(10)
  26643.  
  26644. /*
  26645. ** Security Check
  26646. */
  26647. EXEC @retcode = dbo.sp_MSreplcheck_publish
  26648. IF @@ERROR <> 0 or @retcode <> 0
  26649.     return (1)
  26650.  
  26651. -- check to see if this stored procedure is called via replication agent.
  26652. if sessionproperty('replication_agent')<>1
  26653.     select @from_agent = 0
  26654. else
  26655.     select @from_agent = 1
  26656. select @merge_pub_markcolumn_bit = 0x4000
  26657. select @merge_pub_unmarkcolumn_bit = ~@merge_pub_markcolumn_bit
  26658. select @v_unique_constraint = 4096
  26659. select @v_unique_index      = 2         -- status in sysindexes
  26660.  
  26661. select @qual_column=QUOTENAME(@column)
  26662.  
  26663. select @no_schema_replication = 0
  26664. select @not_for_merge    = 0
  26665. select @merge_pub_object_bit     = 128
  26666. select @objid = object_id(@source_object)
  26667. select @servername=@@SERVERNAME
  26668. select @dbname=db_name()
  26669.  
  26670. if @objid is NULL
  26671. begin
  26672.     --if table does not exists and the SP is called from replication agent, ignore the error and exit with success.
  26673.     if @from_agent=1
  26674.         return (0)
  26675.     else
  26676.         begin
  26677.             raiserror(14027, 16, -1, @source_object)
  26678.             return (1)
  26679.         end
  26680. end
  26681.  
  26682. if not exists (select * from syscolumns where name=@column and id=@objid)
  26683. begin
  26684.     if @from_agent=0
  26685.     begin
  26686.         raiserror(21166, 16, -1, @column)
  26687.         return (1)
  26688.     end
  26689.     else
  26690.         return (0)
  26691. end
  26692.  
  26693. select @indid = indid from sysindexes where id = @objid and (status & 2048) <> 0    /* PK index */
  26694. select @index_cnt = 1
  26695. while (@index_cnt <= 16)
  26696. begin
  26697.     select @pkkey = INDEX_COL(@source_object, @indid, @index_cnt)
  26698.     if @pkkey is NULL
  26699.         break
  26700.     if @pkkey=@column
  26701.     begin
  26702.         raiserror(21264, 16, -1, @column, @source_object)
  26703.         return (1)
  26704.     end
  26705.     select @index_cnt = @index_cnt + 1
  26706. end
  26707.     
  26708. /*
  26709. ** Check for unique index defined on this column - to disallow such a column from being dropped
  26710. */    
  26711. if exists (select * from sysindexes where id=@objid 
  26712.     and (status & @v_unique_index = @v_unique_index 
  26713.             or status & @v_unique_constraint = @v_unique_constraint))
  26714. begin
  26715.     declare @keys varbinary(816)
  26716.     declare @i         int
  26717.     declare #check_unique CURSOR LOCAL FAST_FORWARD for 
  26718.         select indid from sysindexes where id=@objid 
  26719.                 and (status & @v_unique_index = @v_unique_index 
  26720.                     or status & @v_unique_constraint = @v_unique_constraint)
  26721.     open #check_unique
  26722.     fetch #check_unique into @indid
  26723.     while (@@fetch_status<>-1)
  26724.     begin
  26725.         SELECT @i = 1
  26726.         WHILE (@i <= 16)
  26727.         BEGIN
  26728.             SELECT @pkkey = INDEX_COL(@source_object, @indid, @i)
  26729.             if @pkkey is NULL
  26730.                 break
  26731.             if @pkkey=@column
  26732.             BEGIN
  26733.                 raiserror(21265, 16, -1, @column, @source_object)
  26734.                 close #check_unique
  26735.                 deallocate #check_unique
  26736.                 return (1)
  26737.             END
  26738.             select @i = @i + 1
  26739.         END    
  26740.         fetch #check_unique into @indid
  26741.     end
  26742.     close #check_unique
  26743.     deallocate #check_unique
  26744. end
  26745.  
  26746. if exists (select * from sysobjects where name='sysmergearticles')
  26747. begin
  26748.     if @from_agent=0 and exists (select * from sysmergearticles where objid=@objid and pubid not in 
  26749.         (select pubid from sysmergepublications where LOWER(publisher)=LOWER(@@SERVERNAME) and publisher_db=db_name()))
  26750.     begin
  26751.         raiserror(21260, 16, -1, @dbname, @servername, @source_object)
  26752.         return (1)
  26753.     end
  26754. end
  26755.  
  26756. -- if not for TRAN, it has to be a merge publication
  26757. if not exists (select * from sysobjects where name='syspublications')
  26758. begin
  26759.     if not exists (select * from sysmergearticles where objid=@objid)
  26760.         select @no_schema_replication = 1
  26761. end
  26762.  
  26763. -- if not for merge, it has to be a tran publication
  26764. if not exists (select * from sysobjects where name='sysmergepublications')
  26765. begin
  26766.     if not exists (select * from sysarticles where objid=@objid)
  26767.         select @no_schema_replication =1
  26768. end
  26769.  
  26770. if exists (select * from sysobjects where name='sysmergepublications')
  26771.     and exists (select * from sysobjects where name='syspublications')
  26772. begin
  26773.     if not exists (select * from sysarticles where objid=@objid)
  26774.             and not exists (select * from sysmergearticles where objid=@objid)
  26775.         select @no_schema_replication=1
  26776. end
  26777.  
  26778. if @no_schema_replication=1
  26779.     begin
  26780.         raiserror(21246, 16, -1, @source_object)
  26781.         return (1)
  26782.     end
  26783.  
  26784. if exists (select * from sysobjects where name = 'sysmergearticles')
  26785. begin
  26786.     if exists  (select * from sysmergearticles where objid=@objid)
  26787.         select @is_for_merge=1
  26788.     else
  26789.         select @is_for_merge=0
  26790. end
  26791. else
  26792.     select @is_for_merge=0
  26793.  
  26794. -- PARSENAME VARS
  26795.     declare      @UnqualName      sysname  --rightmost name node
  26796.     declare      @QualName1       sysname  
  26797. -- END PARSENAME VARS
  26798.  
  26799.     select @UnqualName = PARSENAME(@source_object, 1)
  26800.     select @QualName1 = PARSENAME(@source_object, 2)
  26801.     if @UnqualName IS NULL
  26802.          return 1
  26803.     if @QualName1 is not NULL
  26804.         select @owner = @QualName1
  26805.             else select @owner=user_name(uid) from dbo.sysobjects where id = @objid
  26806.  
  26807. select @tablename = @UnqualName
  26808. select @qual_source_object = QUOTENAME(@owner) + N'.' + QUOTENAME(@tablename)
  26809. select @at_publisher = 0
  26810. select @colid=colid from dbo.syscolumns where id=@objid and name=@column
  26811. if @colid is NULL
  26812.     begin
  26813.         raiserror(21166, 16, -1, @column)
  26814.         return (1)
  26815.     end
  26816.  
  26817. /*
  26818. ** Considering holes, colid is not necessarily the one in bitmap. Get this value from count(*)
  26819. */
  26820. select @missing_index = count(*) from dbo.syscolumns where id=@objid and colid<=@colid
  26821. begin TRAN
  26822. save tran sp_repldropcolumn
  26823.     if @is_for_merge=1
  26824.     begin
  26825.         exec sp_replupdateschema @qual_source_object
  26826.         if @@ERROR<>0
  26827.             goto FAILURE
  26828.         exec @retcode = sp_MSunmarkreplinfo @object=@tablename, @owner=@owner
  26829.         if @retcode<>0 or @@ERROR<>0
  26830.             goto FAILURE
  26831.         --unmark this column so that it can be dropped
  26832.         update dbo.syscolumns set colstat=colstat & @merge_pub_unmarkcolumn_bit where id=@objid and colid = @colid
  26833.         if @@ERROR<>0 
  26834.             goto FAILURE
  26835.     end
  26836.  
  26837.  
  26838.     select @is_for_tran = 0    
  26839.     if exists (select * from dbo.sysobjects where name='sysarticles')
  26840.     begin
  26841.         if exists (select * from dbo.sysarticles where objid=@objid)
  26842.         begin
  26843.             if exists (SELECT P.pubid FROM dbo.syspublications P, dbo.sysarticles A, dbo.syssubscriptions S 
  26844.                     WHERE A.objid = @objid    and A.pubid = P.pubid and A.artid = S.artid
  26845.                         and (P.allow_sync_tran = 1 or P.allow_queued_tran = 1) 
  26846.                         and S.status = 2  -- active
  26847.                         and S.sync_type != 2 -- not 'none'
  26848.                         and S.update_mode != 0 ) -- not 'read only'
  26849.              and @force_reinit_subscription = 0
  26850.             begin 
  26851.                 raiserror(21381, 16, -1, @tablename)
  26852.                 goto FAILURE
  26853.             end
  26854.  
  26855.             select @is_for_tran =1
  26856.             select pubid, artid, columns 
  26857.                 into #oldcols 
  26858.                 from sysarticles
  26859.                 where objid = @objid
  26860.         end
  26861.     end
  26862.  
  26863.     /*
  26864.     ** First call TRAN Level stored procedure to 
  26865.     */
  26866.     if @is_for_tran = 1
  26867.     begin
  26868.         exec @retcode = sp_MSprep_exclusive @qual_source_object
  26869.         if @@ERROR<>0 or @retcode <> 0
  26870.             goto FAILURE
  26871.  
  26872.         exec @retcode = sp_replincrementlsn @schema_start_lsn OUTPUT
  26873.         if @@ERROR<>0 or @retcode <> 0
  26874.             goto FAILURE
  26875.  
  26876.         exec @retcode = sp_replpostschema @objid
  26877.         if @@ERROR<>0 or @retcode <> 0
  26878.             goto FAILURE
  26879.  
  26880.         declare #trancolumn CURSOR LOCAL FAST_FORWARD for 
  26881.             select a.artid, p.name from sysarticles a, syspublications p where a.objid=@objid
  26882.                     and p.pubid = a.pubid
  26883.         open #trancolumn
  26884.         fetch #trancolumn into @tran_artid, @tran_pubname
  26885.         while (@@fetch_status <> -1)
  26886.         BEGIN
  26887.             select @tran_artname=name from sysarticles where artid=@tran_artid
  26888.             exec @retcode = sp_articlecolumn @publication = @tran_pubname, @article = @tran_artname, @column = @column, 
  26889.                          @operation = 'drop', @change_active = 2
  26890.                         ,@force_invalidate_snapshot = 1
  26891.                         ,@force_reinit_subscription = 1
  26892.             if @retcode <>0 or @@ERROR<>0
  26893.                 goto DROPTRAN
  26894.             fetch #trancolumn into @tran_artid, @tran_pubname            
  26895.         END
  26896.         close #trancolumn
  26897.         deallocate #trancolumn
  26898.     end
  26899.  
  26900.     if not exists (select * from sysobjects where name='sysmergearticles')
  26901.         select @not_for_merge = 1
  26902.     else
  26903.         if not exists (select * from sysmergearticles where objid=@objid)
  26904.             select @not_for_merge =1
  26905.     
  26906.             
  26907.     if @not_for_merge = 1 
  26908.     begin
  26909.         if exists (select * from syscolumns where name=@column and id =@objid)
  26910.         begin
  26911.             exec ('alter table '+ @qual_source_object + ' drop column ' + @qual_column )
  26912.                     if @@ERROR<>0
  26913.                         goto FAILURE
  26914.             
  26915.             exec @retcode = sp_MSverifytranfilter @objid
  26916.             if @@ERROR <> 0 or @retcode <> 0
  26917.             begin
  26918.                 goto FAILURE
  26919.             end                    
  26920.         end
  26921.     end
  26922.     else
  26923.     begin
  26924.         if exists (select * from sysmergepublications where pubid in 
  26925.             (select pubid from sysmergearticles where objid=@objid) and snapshot_ready=0)
  26926.             and exists (select * from syscolumns where name=@column and id =@objid)
  26927.             begin
  26928.                 declare #nosnapshot CURSOR LOCAL FAST_FORWARD for
  26929.                     select p.name, a.name from sysmergepublications p, sysmergearticles a 
  26930.                         where p.pubid=a.pubid and a.objid=@objid and p.snapshot_ready=0
  26931.                 open #nosnapshot
  26932.                 fetch #nosnapshot into @pubname, @artname
  26933.                 while (@@fetch_status<>-1)
  26934.                 begin
  26935.                     exec @retcode = sp_mergearticlecolumn @pubname, @artname, @column, 'drop', 'true'
  26936.                     if @retcode <>0 or @@ERROR<>0
  26937.                         goto ERROR_EXIT
  26938.                     fetch #nosnapshot into @pubname, @artname
  26939.                 end
  26940.                 close #nosnapshot
  26941.                 deallocate #nosnapshot
  26942.             end
  26943.  
  26944.         declare #dropcolumn_schema CURSOR LOCAL FAST_FORWARD fast_forward for 
  26945.                 select name, pubid, artid, destination_owner, columns from sysmergearticles where objid=@objid and pubid
  26946.                             in (select pubid from sysmergepublications where snapshot_ready>0) order by pubid ASC
  26947.         open #dropcolumn_schema
  26948.         fetch #dropcolumn_schema into @artname, @pubid, @artid, @dest_owner, @columnbm
  26949.         while (@@fetch_status <> -1)
  26950.         BEGIN
  26951.                 if @dest_owner is not NULL
  26952.                     select @dest_object = QUOTENAME(@dest_owner) + N'.' + QUOTENAME(@tablename)
  26953.                 else
  26954.                     select @dest_object = QUOTENAME(@tablename)
  26955.  
  26956.                 exec @in_partition = sp_MStestbit @bm=@columnbm, @coltotest=@colid
  26957.  
  26958.                 select @pubname=name, @publisher=publisher, @publisher_db=publisher_db
  26959.                     from sysmergepublications where pubid=@pubid
  26960.                 select @at_publisher=0
  26961.                 if @publisher=@@SERVERNAME and @publisher_db=db_name() and @in_partition<>0
  26962.                 begin
  26963.                     select @at_publisher=1
  26964.                     select @schematext = 'exec sp_repldropcolumn ''' + @dest_object + ''', ''' + @column + ''', 1'
  26965.                     select @schemaversion = schemaversion from sysmergeschemachange
  26966.                     if (@schemaversion is NULL)
  26967.                         set @schemaversion = 1
  26968.                     else
  26969.                         select @schemaversion = 1 + max(schemaversion) from sysmergeschemachange        
  26970.                     set @schemaguid = newid()
  26971.                     set @schematype = 11 /* alter table */
  26972.                     exec @retcode = sp_mergearticlecolumn @pubname, @artname, @column, 'drop', 'true'
  26973.                     if @retcode<>0 or @@ERROR<>0
  26974.                         goto INNER_FAIL2 -- need to deallocate cursor for this loop.
  26975.                     exec @retcode=sp_MSinsertschemachange @pubid, @artid, @schemaversion, @schemaguid, @schematype, @schematext
  26976.                     if @@ERROR<>0 or @retcode<>0 
  26977.                         goto INNER_FAIL2
  26978.                         
  26979.                     select @schematext = 'alter table ' +  @dest_object + ' drop column ' + @column 
  26980.                     select @schemaversion = @schemaversion + 1
  26981.                     set @schematype = 13 -- for Jet use only
  26982.                     set @schemaguid = newid()
  26983.                     exec @retcode=sp_MSinsertschemachange @pubid, @artid, @schemaversion, @schemaguid, @schematype, @schematext                        
  26984.                     if @@ERROR<>0 or @retcode<>0 
  26985.                         goto INNER_FAIL2
  26986.                 end
  26987.             fetch #dropcolumn_schema into @artname, @pubid, @artid, @dest_owner, @columnbm
  26988.         END
  26989.         close #dropcolumn_schema
  26990.         deallocate #dropcolumn_schema
  26991.  
  26992.         /* drop the column only once */
  26993.         if exists (select  *  from syscolumns where id=@objid and name=@column)
  26994.         begin
  26995.             select @command = 'alter table ' + @qual_source_object + ' drop column ' + @qual_column
  26996.             exec (@command)
  26997.             if @@ERROR<>0
  26998.                 GOTO INNER_FAIL
  26999.  
  27000.             -- if transactionally replicated, verify that filter columns weren't dropped
  27001.  
  27002.             if( @is_for_tran = 1 )
  27003.             begin
  27004.                 exec @retcode = sp_MSverifytranfilter @objid
  27005.                 if @@ERROR <> 0 or @retcode <> 0
  27006.                 begin
  27007.                     goto FAILURE
  27008.                 end                    
  27009.             end
  27010.         end
  27011.         declare #dropcolumn CURSOR LOCAL FAST_FORWARD fast_forward for 
  27012.                 select pubid, name, sync_objid, artid, missing_col_count, missing_cols, 
  27013.                     conflict_table, ins_conflict_proc from sysmergearticles where objid=@objid and pubid
  27014.                             in (select pubid from sysmergepublications where snapshot_ready>0) order by pubid ASC
  27015.         open #dropcolumn
  27016.         fetch #dropcolumn into @pubid, @artname, @sync_objid, @artid, 
  27017.                 @missing_count, @missing_bm, @conflict_table, @ins_conflict_proc
  27018.         while (@@fetch_status <> -1)
  27019.         BEGIN                
  27020.             select @pubname=name, @publisher=publisher, @publisher_db=publisher_db
  27021.                 from sysmergepublications where pubid=@pubid
  27022.             select @at_publisher=0
  27023.             if @publisher=@@SERVERNAME and @publisher_db=db_name()
  27024.                 select @at_publisher=1
  27025.  
  27026.             if @conflict_table is not NULL 
  27027.             begin
  27028.                 select @con_id = object_id(@conflict_table)
  27029.                 if @con_id is NULL
  27030.                 begin
  27031.                     raiserror(21286, 16, -1, @conflict_table)
  27032.                     GOTO INNER_FAIL
  27033.                 end
  27034.  
  27035.             select @colid=colid from syscolumns where id = @con_id and name=@column            
  27036.             
  27037.     
  27038.                 if exists (select name from syscolumns where name=@column and id=@con_id)
  27039.                 begin
  27040.                     select @command = 'alter table ' + QUOTENAME(@conflict_table) + ' drop column ' + @qual_column
  27041.                     exec (@command)
  27042.                     if @@ERROR<>0
  27043.                         goto INNER_FAIL
  27044.                 end
  27045.             end
  27046.  
  27047.             /*
  27048.             ** Force the re-generation of conflict insert table cause the schema is changed for sure
  27049.             */
  27050.             if @ins_conflict_proc is not NULL and object_id(@ins_conflict_proc) is not NULL
  27051.             begin
  27052.                 exec ('drop procedure ' + @ins_conflict_proc)
  27053.                 if @@ERROR<>0
  27054.                     goto INNER_FAIL
  27055.                 update sysmergearticles set ins_conflict_proc=NULL where pubid=@pubid and artid=@artid
  27056.                 if @@ERROR<>0
  27057.                     goto INNER_FAIL
  27058.             end
  27059.     
  27060.             if @at_publisher=1
  27061.             begin
  27062.                 exec @retcode = sp_MSpublicationview @pubname, 1
  27063.                 if @retcode<>0 or @@ERROR<>0
  27064.                 begin
  27065.                     raiserror(21201, 16, -1) 
  27066.                     goto INNER_FAIL
  27067.                 end
  27068.             end
  27069.             select @missing_count=@missing_count + 1
  27070.             select @old_missing_bm=@missing_bm
  27071.             exec @retcode=sp_MSsetbit @missing_bm OUTPUT, @missing_index
  27072.             if @retcode<>0 or @@ERROR<>0
  27073.                 goto INNER_FAIL
  27074.             --if no change, that is, the column is already marked as missing, do not increase 
  27075.             --its count
  27076.             if @missing_bm<>@old_missing_bm
  27077.             begin
  27078.                 update sysmergearticles set missing_col_count=@missing_count, missing_cols=@missing_bm
  27079.                     where pubid=@pubid and artid=@artid
  27080.                 if @@ERROR<>0
  27081.                 goto INNER_FAIL
  27082.             end
  27083.             
  27084.                 
  27085.             exec @retcode = sp_MSdroparticletriggers @qual_source_object
  27086.             if @retcode<>0 or @@ERROR<>0
  27087.                 goto INNER_FAIL
  27088.             exec @retcode = sp_MSaddmergetriggers @qual_source_object
  27089.             if @retcode<>0 or @@ERROR<>0
  27090.                 goto INNER_FAIL
  27091.             exec @retcode = sp_MSsetartprocs @publication=@pubname, @article=@artname, @force_flag=1
  27092.             if @retcode<>0 or @@ERROR<>0
  27093.                 goto INNER_FAIL
  27094.             /*
  27095.             ** passing in one more parameter to sp_MSgetconflictinsertproc such that there is 
  27096.             ** no select statement at the end of that SP as needed else where. The default is 1.
  27097.             */
  27098.             exec @retcode = sp_MSgetconflictinsertproc @artid, @pubid, 0
  27099.             if @retcode<>0 or @@ERROR<>0
  27100.                 goto INNER_FAIL
  27101.  
  27102.             fetch #dropcolumn into @pubid, @artname, @sync_objid, @artid, 
  27103.                 @missing_count, @missing_bm, @conflict_table, @ins_conflict_proc
  27104.         END
  27105.         CLOSE #dropcolumn
  27106.         DEALLOCATE #dropcolumn
  27107.     
  27108.         if @is_for_merge=1
  27109.         begin
  27110.             exec @retcode = sp_MSmarkreplinfo @tablename, @owner
  27111.             if @retcode<>0 or @@ERROR<>0
  27112.                 goto FAILURE
  27113.         end
  27114.     end
  27115.  
  27116. -- finally, if it's transactional, trigger a reinit
  27117. if @is_for_tran = 1
  27118. begin
  27119.  
  27120.     if exists (select * from sysarticles where objid = @objid)
  27121.     begin
  27122.         declare #trancolumn CURSOR LOCAL FAST_FORWARD for 
  27123.             select a.artid, p.name 
  27124.             from sysarticles a, syspublications p, #oldcols oc
  27125.             where a.objid=@objid
  27126.             and p.pubid = a.pubid
  27127.             and oc.artid = a.artid
  27128.             and oc.columns <> a.columns
  27129.  
  27130.         open #trancolumn
  27131.         fetch #trancolumn into @tran_artid, @tran_pubname
  27132.         while (@@fetch_status <> -1)
  27133.         BEGIN
  27134.             select @tran_artname=name, @tran_pubid = pubid, @owner = dest_owner, @tablename = dest_table from sysarticles where artid=@tran_artid
  27135.             if(@force_reinit_subscription = 0)
  27136.             begin 
  27137.                 if(@owner is not NULL) and (len(@owner) > 0)
  27138.                     select @qual_dest_object = QUOTENAME(@owner) + N'.' 
  27139.                 else 
  27140.                     select @qual_dest_object = N'' 
  27141.                 if(@tablename is not null) and (len(@tablename) > 0)
  27142.                     select @qual_dest_object = @qual_dest_object + QUOTENAME(@tablename)
  27143.                 else 
  27144.                     select @qual_dest_object = @qual_source_object
  27145.                 exec @retcode = sp_MSrepl_schema @pubname = @tran_pubname 
  27146.                             ,@artid = @tran_artid
  27147.                             ,@qual_source_object = @qual_dest_object
  27148.                             ,@column = @column
  27149.                             ,@operation = 1 -- 0 is add, 1 is delete
  27150.                             ,@schema_change_script = @schema_change_script
  27151.                 if @retcode <>0 or @@ERROR<>0
  27152.                     goto DROPTRAN
  27153.             end
  27154.             exec @retcode = dbo.sp_MSreinit_article 
  27155.                             @publication = @tran_pubname
  27156.                             ,@article = @tran_artname
  27157.                             ,@need_new_snapshot = @force_invalidate_snapshot
  27158.                             ,@need_reinit_subscription = @force_reinit_subscription
  27159.                             ,@force_invalidate_snapshot = @force_invalidate_snapshot
  27160.                             ,@force_reinit_subscription = @force_reinit_subscription
  27161.             if @retcode <>0 or @@ERROR<>0
  27162.                 goto DROPTRAN
  27163.             fetch #trancolumn into @tran_artid, @tran_pubname            
  27164.         END
  27165.         close #trancolumn
  27166.         deallocate #trancolumn
  27167.          exec @retcode = sp_replincrementlsn @schema_end_lsn OUTPUT
  27168.          if @@ERROR<>0 or @retcode <> 0
  27169.              goto FAILURE
  27170.          if (@schema_start_lsn is not null) and (@schema_end_lsn is not null)
  27171.          begin
  27172.              insert systranschemas (tabid, startlsn, endlsn) values (@objid, @schema_start_lsn, @schema_end_lsn)
  27173.              if @@ERROR<>0
  27174.                  goto FAILURE
  27175.              exec @retcode = sp_replflush @objid, @schema_start_lsn, @schema_end_lsn
  27176.              if @@ERROR<>0 or @retcode <> 0
  27177.                  goto FAILURE
  27178.          end
  27179.          else
  27180.              goto FAILURE
  27181.     end
  27182. end
  27183.  
  27184.  
  27185. COMMIT TRAN
  27186. return (0)
  27187.  
  27188. DROPTRAN:
  27189. CLOSE #trancolumn
  27190. DEALLOCATE #trancolumn
  27191. GOTO FAILURE
  27192.  
  27193. INNER_FAIL:
  27194. CLOSE #dropcolumn
  27195. DEALLOCATE #dropcolumn
  27196. GOTO FAILURE
  27197.  
  27198. INNER_FAIL2:
  27199. CLOSE #dropcolumn_schema
  27200. DEALLOCATE #dropcolumn_schema
  27201. GOTO FAILURE
  27202.  
  27203.  
  27204. ERROR_EXIT:
  27205. CLOSE #nosnapshot
  27206. DEALLOCATE #nosnapshot
  27207.  
  27208. FAILURE:
  27209.     rollback tran sp_repldropcolumn
  27210.     commit tran
  27211.     raiserror(21284, 16, -1, @column, @source_object)
  27212.     return (1)    
  27213. go
  27214.  
  27215. exec dbo.sp_MS_marksystemobject sp_repldropcolumn 
  27216. go
  27217. grant execute on dbo.sp_repldropcolumn to public
  27218. go
  27219. raiserror('Creating procedure sp_repladdcolumn', 0,1)
  27220. GO
  27221.  
  27222. CREATE PROCEDURE sp_repladdcolumn(
  27223.     @source_object          nvarchar (358),
  27224.     @column                    sysname,
  27225.     @typetext                 nvarchar(3000),
  27226.     @publication_to_add        nvarchar(4000) = 'all',
  27227.     @from_agent                int = 0, 
  27228.     @schema_change_script    nvarchar(4000) = NULL,
  27229.     @force_invalidate_snapshot bit = 1,    /* Force invalidate existing snapshot */
  27230.     @force_reinit_subscription bit = 0    /* Force reinit subscription */
  27231.     )
  27232. as
  27233. set nocount on
  27234. declare @objid            int
  27235. declare @pubid            uniqueidentifier
  27236. declare @retcode        int
  27237. declare @partitioned    int
  27238. declare @at_publisher    bit
  27239. declare @pubname        sysname
  27240. declare @artname        sysname
  27241. declare @colid            int
  27242. declare @tablename        sysname
  27243. declare @artid            uniqueidentifier
  27244. declare @tran_artid        int
  27245. declare @tran_pubid        int
  27246. declare @schematext        nvarchar(4000)
  27247. declare @schemaversion    int
  27248. declare @schematype        int
  27249. declare @schemaguid        uniqueidentifier
  27250. declare @conflict_table    sysname
  27251. declare @ins_conflict_proc sysname
  27252. declare @publisher        sysname
  27253. declare @qual_column    nvarchar(140)
  27254. declare @not_for_merge    int
  27255. declare @publisher_db    sysname
  27256. declare @command        nvarchar(3000)
  27257. declare @sync_objid        int
  27258. declare @con_id            int
  27259. declare @owner            sysname
  27260. declare @dest_owner        sysname
  27261. declare @dest_object    nvarchar(386)
  27262. declare @merge_pub_object_bit    int
  27263. declare @is_for_merge    bit
  27264. declare @is_for_tran    bit
  27265. declare @dbname            sysname
  27266. declare @servername        sysname
  27267. declare @no_publication bit
  27268. declare @no_schema_replication bit
  27269. declare @qual_source_object nvarchar(362)
  27270. declare @len             int
  27271. declare @prec             int
  27272. declare @scale int
  27273. declare @typename nvarchar(270)
  27274. declare @qual_dest_object nvarchar(362)
  27275. declare @invalid_datatype    bit
  27276. declare @is_identity_or_timestamp bit
  27277. declare @xtype         int
  27278. declare @iscomputed bit
  27279. declare @pass_to_heterogenious bit
  27280. declare @merge_pub_markcolumn_bit    int
  27281. declare @schema_start_lsn binary(10)
  27282. declare @schema_end_lsn binary(10)
  27283. declare @nickname         int
  27284. declare @columns_in_partition    int
  27285. /*
  27286. ** Security Check
  27287. */
  27288. EXEC @retcode = dbo.sp_MSreplcheck_publish
  27289. IF @@ERROR <> 0 or @retcode <> 0
  27290.     return (1)
  27291.  
  27292.  
  27293. select @qual_column=QUOTENAME(@column)
  27294. select @merge_pub_markcolumn_bit = 0x4000
  27295.  
  27296. select @objid = object_id(@source_object)
  27297.  
  27298. -- check to see if this stored procedure is called via replication agent.
  27299. if sessionproperty('replication_agent')<>1
  27300.     select @from_agent = 0
  27301. else
  27302.     begin --if table does not exists and the SP is called from replication agent, ignore the error and exit with success.
  27303.         select @from_agent = 1
  27304.         if @objid is NULL
  27305.             return (0)
  27306.     end
  27307.  
  27308. if @objid is NULL
  27309. begin
  27310.     raiserror(14027, 16, -1, @source_object)
  27311.     return (1)
  27312. end
  27313.  
  27314. if exists (select * from syscolumns where id=@objid and name=@column)
  27315. begin
  27316.     if @from_agent=0
  27317.     begin
  27318.         raiserror(21255, 16, -1, @column, @source_object)
  27319.         return (1)
  27320.     end
  27321.     else
  27322.         return (0)
  27323. end
  27324.  
  27325.  
  27326. -- PARSENAME VARS
  27327.     declare      @UnqualName      sysname  --rightmost name node
  27328.     declare      @QualName1       sysname  
  27329. -- END PARSENAME VARS
  27330.  
  27331.     select @UnqualName = PARSENAME(@source_object, 1)
  27332.     select @QualName1 = PARSENAME(@source_object, 2)
  27333.     if @UnqualName IS NULL
  27334.          return 1
  27335.     if @QualName1 is not NULL
  27336.         select @owner = @QualName1
  27337.             else select @owner=user_name(uid) from sysobjects where id = @objid
  27338.     select @tablename = @UnqualName
  27339.  
  27340.     select @qual_source_object = QUOTENAME(@owner) + '.' + QUOTENAME(@tablename)
  27341. select @no_schema_replication = 0
  27342. select @no_publication=0
  27343. select @servername=@@SERVERNAME
  27344. select @dbname=db_name()
  27345. select @merge_pub_object_bit     = 128
  27346. select @not_for_merge = 0
  27347.  
  27348. if exists (select * from sysobjects where name='sysmergearticles')
  27349. begin
  27350.     if @from_agent=0 and exists (select * from sysmergearticles where objid=@objid and pubid not in 
  27351.         (select pubid from sysmergepublications where LOWER(publisher)=LOWER(@servername) and publisher_db=@dbname))
  27352.     begin
  27353.         raiserror(21260, 16, -1, @dbname, @servername, @source_object)
  27354.         return (1)
  27355.     end
  27356. end
  27357.  
  27358. select @invalid_datatype=0
  27359.  
  27360. /* the transaction below is just an experiment to validate type text */
  27361. BEGIN TRAN
  27362. SAVE TRANSACTION fake_move
  27363.     exec @retcode = sp_MSunmarkreplinfo @object=@tablename, @owner=@owner
  27364.     if @retcode<>0 or @@ERROR<>0
  27365.     begin
  27366.         goto CHECKING_DONE
  27367.     end
  27368.     declare @temp_id         int
  27369.     declare @temp_colid     int
  27370.     select @is_identity_or_timestamp = 0
  27371.     exec ('alter table ' + @qual_source_object + ' add ' + @qual_column + ' ' + @typetext)
  27372.     select @temp_id = object_id(@qual_source_object)
  27373.     if @temp_id is NULL
  27374.     begin
  27375.         raiserror(21285, 16, -1, @column, @source_object)
  27376.         select @invalid_datatype = 1
  27377.         GOTO CHECKING_DONE
  27378.     end
  27379.     select @pass_to_heterogenious=0, @temp_colid = colid, @xtype=xtype, @iscomputed=iscomputed 
  27380.         from syscolumns where id = @temp_id and name=@column
  27381.     if @iscomputed <> 1 and type_name(@xtype) <> 'timestamp'
  27382.         select @pass_to_heterogenious=1
  27383.     if COLUMNPROPERTY(@temp_id, @column, 'IsIdentity') = 1 or type_name(@xtype) = 'timestamp'
  27384.         select @is_identity_or_timestamp = 1
  27385.     if COLUMNPROPERTY(@temp_id, @column, 'IsIdentity') = 0
  27386.         and not exists (select * from syscolumns where id = @temp_id and name=@column and isnullable=1)
  27387.         and not exists (select * from sysconstraints where id=@temp_id and colid=@temp_colid and status & 5 = 5)
  27388.         and @iscomputed <> 1 and type_name(@xtype) <> 'timestamp'  --not computed column nor timestamp column
  27389.     begin
  27390.         select @invalid_datatype = 1
  27391.     end
  27392. CHECKING_DONE:
  27393. ROLLBACK TRANSACTION fake_move
  27394. COMMIT TRAN
  27395. if @invalid_datatype = 1
  27396.     begin
  27397.         raiserror(21285, 16, -1, @column, @source_object)
  27398.         return (1)
  27399.     end
  27400.     
  27401. if exists (select * from sysobjects where id=@objid and replinfo & @merge_pub_object_bit <>0)
  27402.     select @is_for_merge = 1
  27403. else
  27404.     select @is_for_merge = 0
  27405. select @is_for_tran = 0
  27406. if not exists (select * from sysobjects where name='sysmergepublications') and
  27407.     not exists (select * from sysobjects where name='syspublications')
  27408. begin
  27409.     raiserror(21230, 16, -1)
  27410.     return (1)
  27411. end
  27412.  
  27413. create table #tmp_table (name sysname collate database_default)
  27414.  
  27415. if LOWER(@publication_to_add)='all' or LOWER(@publication_to_add)='[all]'
  27416. begin    
  27417.     select @publication_to_add = '%'
  27418. end
  27419. else 
  27420. begin
  27421. if charindex(',', @publication_to_add)<>0 --publication list
  27422.     begin
  27423.         declare @tmp_publist    nvarchar(4000)
  27424.         declare @total             int
  27425.         declare @invalid_pub    sysname
  27426.         select @invalid_pub = NULL
  27427.             select @tmp_publist = @publication_to_add
  27428.         while @tmp_publist <> ''
  27429.         begin
  27430.             select @tmp_publist = LTRIM(@tmp_publist)
  27431.             select @total=len(@tmp_publist)
  27432.             select @len=charindex(',', @tmp_publist)
  27433.             if @len=0
  27434.                 begin
  27435.                     insert #tmp_table values(@tmp_publist)
  27436.                     select @tmp_publist=''
  27437.                 end
  27438.             else
  27439.                 begin
  27440.                     insert #tmp_table values(substring(@tmp_publist, 1, @len-1))
  27441.                     select @tmp_publist = right(@tmp_publist, @total-@len)
  27442.                 end
  27443.         end
  27444.         if exists (select * from sysobjects where name='sysmergepublications') and 
  27445.             exists (select * from sysobjects where name='syspublications')
  27446.             select @invalid_pub=name from #tmp_table where name not in (select ('[' + name + ']') from sysmergepublications) and 
  27447.                                                             name not in (select ('[' + name + ']') from syspublications)
  27448.         else 
  27449.             if exists (select * from sysobjects where name='sysmergepublications') 
  27450.                 select @invalid_pub=name from #tmp_table where name not in (select ('[' + name + ']') from sysmergepublications)            
  27451.             else
  27452.                 if exists (select * from sysobjects where name='syspublications')         
  27453.                     select @invalid_pub=name from #tmp_table where name not in (select ('[' + name + ']') from syspublications)                        
  27454.         if @invalid_pub is not NULL and @from_agent=0
  27455.         begin
  27456.             raiserror(21274, 16, -1, @invalid_pub)
  27457.             return (1)        
  27458.         end
  27459.     end
  27460. else 
  27461.     begin --single publication
  27462.         insert #tmp_table values(@publication_to_add)
  27463.         insert #tmp_table values('[' + @publication_to_add + ']')
  27464.     end
  27465.     
  27466. end
  27467.  
  27468.  
  27469.  
  27470. -- if not for TRAN, it has to be a merge publication
  27471. if not exists (select * from sysobjects where name='syspublications')
  27472. begin
  27473.     if not exists (select * from sysmergepublications where name like @publication_to_add 
  27474.                 or (('[' + name + ']') in (select name from #tmp_table)))
  27475.         select @no_publication = 1
  27476.  
  27477.     if not exists (select * from sysmergearticles where objid=@objid and pubid in 
  27478.             (select pubid from sysmergepublications where name like @publication_to_add 
  27479.                     or (('[' + name + ']') in (select name from #tmp_table))))
  27480.         select @no_schema_replication = 1
  27481. end
  27482.  
  27483. -- if not for merge, it has to be a tran publication
  27484. if not exists (select * from sysobjects where name='sysmergepublications')
  27485. begin
  27486.     if not exists (select * from syspublications where name like @publication_to_add 
  27487.                 or (('[' + name + ']') in (select name from #tmp_table))) 
  27488.         select @no_publication = 1
  27489.         
  27490.     if not exists (select * from sysarticles where objid=@objid and pubid in 
  27491.             (select pubid from syspublications where name like @publication_to_add 
  27492.                 or (('[' + name + ']') in (select name from #tmp_table))))
  27493.         select @no_schema_replication =1
  27494. end
  27495.  
  27496. if exists (select * from sysobjects where name='sysmergepublications')
  27497.     and exists (select * from sysobjects where name='syspublications')
  27498. begin
  27499.     if not exists (select * from syspublications where name like @publication_to_add 
  27500.                 or (('[' + name + ']') in (select name from #tmp_table)))
  27501.             and not exists (select * from sysmergepublications where name like @publication_to_add 
  27502.                 or (('[' + name + ']') in (select name from #tmp_table)))
  27503.         select @no_publication = 1
  27504.  
  27505.     if not exists (select * from sysarticles where objid=@objid and pubid in 
  27506.             (select pubid from syspublications where name like @publication_to_add 
  27507.                 or (('[' + name + ']') in (select name from #tmp_table))))
  27508.         and not exists (select * from sysmergearticles where objid=@objid and pubid in 
  27509.             (select pubid from sysmergepublications where name like @publication_to_add 
  27510.                     or (('[' + name + ']') in (select name from #tmp_table))))
  27511.         select @no_schema_replication=1
  27512. end
  27513.  
  27514. if @no_publication=1 and @publication_to_add <> '%' and LOWER(@publication_to_add)<>'none' and LOWER(@publication_to_add)<>'[none]'
  27515.     begin
  27516.         raiserror(21200, 16, -1, @publication_to_add)
  27517.         return (1)
  27518.     end
  27519.  
  27520. if @no_schema_replication=1 and LOWER(@publication_to_add)<>'none' and LOWER(@publication_to_add)<>'[none]'
  27521.     begin
  27522.         if @publication_to_add = '%'
  27523.             begin
  27524.                 raiserror(21246, 16, -1, @source_object)
  27525.                 return (1)
  27526.             end
  27527.         else
  27528.             begin
  27529.                 raiserror(21245, 16, -1, @source_object, @publication_to_add)
  27530.                 return (1)
  27531.             end
  27532.     end
  27533.  
  27534. select @at_publisher = 0
  27535.  
  27536. if exists (select * from sysobjects where name = 'sysarticles')
  27537. begin
  27538.     if exists (select a.objid from sysarticles a, syspublications p where a.objid=@objid
  27539.                 and p.pubid = a.pubid
  27540.                 and (p.name like @publication_to_add or charindex('[' + p.name + ']', @publication_to_add)>0))
  27541.     begin
  27542.         select @is_for_tran = 1
  27543.     end
  27544. end
  27545.  
  27546. if (@is_for_tran =1 and @force_reinit_subscription = 0)
  27547. begin
  27548.     if (@is_identity_or_timestamp  = 1 )
  27549.     begin
  27550.         raiserror(21380, 16, -1)
  27551.         return (1)
  27552.     end
  27553.     if exists (SELECT P.pubid FROM dbo.syspublications P, dbo.sysarticles A, dbo.syssubscriptions S 
  27554.                     WHERE A.objid = @objid    and A.pubid = P.pubid and A.artid = S.artid
  27555.                         and (P.allow_sync_tran = 1 or P.allow_queued_tran = 1) 
  27556.                         and S.status = 2  -- active
  27557.                         and S.sync_type != 2 -- not 'none'
  27558.                         and S.update_mode != 0 ) -- not 'read only'
  27559.  
  27560.     begin 
  27561.         raiserror(21381, 16, -1, @tablename)
  27562.         return (1)
  27563.     end
  27564. end
  27565.  
  27566. begin TRAN
  27567. save tran sp_repladdcolumn
  27568.     if @is_for_merge=1
  27569.     begin
  27570.         exec sp_replupdateschema @qual_source_object
  27571.          if @@ERROR<>0
  27572.             goto FAILURE
  27573.         
  27574.         exec @retcode = sp_MSunmarkreplinfo @object=@tablename, @owner=@owner
  27575.         if @retcode<>0 or @@ERROR<>0
  27576.             goto FAILURE
  27577.     end
  27578.     if not exists (select * from sysobjects where name='sysmergearticles')
  27579.         select @not_for_merge = 1
  27580.     else
  27581.         if not exists (select * from sysmergearticles where objid=@objid)
  27582.             select @not_for_merge =1
  27583.  
  27584.     if @is_for_tran = 1
  27585.     begin
  27586.         if not exists (select * from syscolumns where name=@column and id =@objid)
  27587.         begin
  27588.             exec @retcode = sp_MSprep_exclusive @qual_source_object
  27589.             if @@ERROR<>0 or @retcode <> 0
  27590.                 goto FAILURE
  27591.             exec @retcode = sp_replincrementlsn @schema_start_lsn OUTPUT
  27592.             if @@ERROR<>0 or @retcode <> 0
  27593.                 goto FAILURE
  27594.             exec @retcode = sp_replpostschema @objid
  27595.             if @@ERROR<>0 or @retcode <> 0
  27596.                 goto FAILURE
  27597.             exec ('alter table '+ @qual_source_object + ' add ' + @qual_column + ' ' + @typetext )
  27598.                 if @@ERROR<>0
  27599.                     goto FAILURE
  27600.         end
  27601.     end
  27602.     if @not_for_merge = 0
  27603.     begin        
  27604.         if  not exists (select * from syscolumns where name=@column and id =@objid)
  27605.             begin
  27606.                 exec ('alter table '+ @qual_source_object + ' add ' + @qual_column + ' ' + @typetext )
  27607.                 if @@ERROR<>0
  27608.                     goto FAILURE
  27609.             end
  27610.  
  27611.         /*
  27612.         ** whether the column is added to this publication, the articles whose underlying table contains
  27613.         ** a new column will be regareded as vertically partitioned.
  27614.         */ 
  27615.         update sysmergearticles set vertical_partition=1 where objid=@objid
  27616.         if @@ERROR<>0
  27617.             goto FAILURE
  27618.  
  27619.         /*
  27620.         ** Heterogenious subscriber are not to receive computed column or timestamp columns
  27621.         */
  27622.         declare #nosnapshot CURSOR LOCAL FAST_FORWARD for
  27623.             select p.name, a.name, a.pubid from sysmergepublications p, sysmergearticles a 
  27624.                     where p.pubid=a.pubid and a.objid=@objid and p.snapshot_ready=0 and (p.name like @publication_to_add or charindex('[' + p.name + ']', @publication_to_add)>0)
  27625.                             and (p.sync_mode=0 or @pass_to_heterogenious=1)                    
  27626.             open #nosnapshot
  27627.             fetch #nosnapshot into @pubname, @artname, @pubid
  27628.                 while (@@fetch_status<>-1)
  27629.                 begin
  27630.                     exec @retcode = sp_mergearticlecolumn @pubname, @artname, @column, 'add', 'true'
  27631.                     if @retcode <>0 or @@ERROR<>0
  27632.                         goto ERROR_EXIT
  27633.                     fetch #nosnapshot into @pubname, @artname, @pubid                    
  27634.                 end
  27635.         CLOSE #nosnapshot
  27636.         DEALLOCATE #nosnapshot
  27637.                 
  27638.         
  27639.         /*
  27640.         ** Handle those cases where snapshot is already ran and new schema change needs to be added
  27641.         ** ; Heterogenious subscriber are not to receive computed column or timestamp columns
  27642.         */
  27643.         declare #addcolumn CURSOR LOCAL FAST_FORWARD fast_forward for 
  27644.                 select pubid, name, sync_objid, artid, conflict_table, ins_conflict_proc, destination_owner
  27645.                     from sysmergearticles where objid=@objid and pubid
  27646.                         in (select pubid from sysmergepublications where snapshot_ready>0 
  27647.                             and (sync_mode=0 or @pass_to_heterogenious=1))
  27648.         open #addcolumn
  27649.         fetch #addcolumn into @pubid, @artname, @sync_objid, @artid, @conflict_table, @ins_conflict_proc, @dest_owner
  27650.         while (@@fetch_status <> -1)
  27651.         BEGIN
  27652.                 if @dest_owner is not NULL
  27653.                     select @dest_object = QUOTENAME(@dest_owner) + '.' + QUOTENAME(@tablename)
  27654.                 else
  27655.                     select @dest_object = QUOTENAME(@tablename)
  27656.  
  27657.                 select @pubname=name, @publisher=publisher, @publisher_db=publisher_db
  27658.                     from sysmergepublications where pubid=@pubid
  27659.  
  27660.                 if @conflict_table is not NULL 
  27661.                 begin
  27662.                     select @con_id = object_id(@conflict_table)
  27663.                     if @con_id is NULL
  27664.                         begin
  27665.                             raiserror(21286, 16, -1, @conflict_table)
  27666.                             GOTO INNER_FAIL
  27667.                         end
  27668.                     if not exists (select name from syscolumns where name=@column and id=@con_id) and (@pubname like @publication_to_add or charindex('[' + @pubname + ']', @publication_to_add)>0)
  27669.                     begin
  27670.                         select @typename = type_name(xtype), @len = length, @prec = COLUMNPROPERTY(id, name, 'precision'),
  27671.                                 @scale = scale, @iscomputed=iscomputed, @xtype=xtype    
  27672.                             from syscolumns where name=@column and id=@objid
  27673.                         --we want to column property of 'computed' or 'timestamp' of the newly added column
  27674.                         if @iscomputed <> 1 and type_name(@xtype) <> 'timestamp'
  27675.                         begin
  27676.                             if @typename='nvarchar' or @typename='nchar' -- a unit of nchar takes 2 bytes 
  27677.                                 select @len = @len/2
  27678.                             exec @retcode = dbo.sp_MSmaptype @typename out, @len, @prec, @scale
  27679.                             if @@error<>0 OR @retcode <>0 
  27680.                                 GOTO INNER_FAIL
  27681.                             --doing so instead of using @typetext as we once did is that we do not want any constraint or identity properties 
  27682.                             --defined on conflict tables. Also it is safe to make the column NULLable in conflict tables.
  27683.                             select @command = 'alter table ' + QUOTENAME(@conflict_table) + ' add ' + @qual_column + ' ' + @typename + ' NULL '
  27684.                         end
  27685.                         else
  27686.                         --continue to use typetext when adding computed/timestamp column to the conflict tables.
  27687.                         begin
  27688.                             select @command = 'alter table ' + QUOTENAME(@conflict_table) + ' add ' + @qual_column + ' ' + @typetext                        
  27689.                         end
  27690.                         exec (@command)
  27691.                         if @@ERROR<>0
  27692.                         goto INNER_FAIL
  27693.  
  27694.                     end
  27695.                 end
  27696.             
  27697.             /*
  27698.             ** Force the re-generation of conflict insert table cause the schema is changed for sure
  27699.             */
  27700.                 if @ins_conflict_proc is not NULL and object_id(@ins_conflict_proc) is not NULL and (@pubname like @publication_to_add or charindex('[' + @pubname + ']', @publication_to_add)>0)
  27701.                 begin
  27702.                     exec ('drop procedure ' + @ins_conflict_proc)
  27703.                     if @@ERROR<>0
  27704.                         goto INNER_FAIL
  27705.                     update sysmergearticles set ins_conflict_proc=NULL where pubid=@pubid and artid=@artid
  27706.                     if @@ERROR<>0
  27707.                         goto INNER_FAIL
  27708.                 end
  27709.  
  27710.             /*
  27711.             ** Force the regeneration of publication view for all publications that publish the current table.
  27712.             */
  27713.                 update sysmergearticles set vertical_partition=1 where artid=@artid and pubid=@pubid
  27714.                 if @@ERROR<>0
  27715.                     goto INNER_FAIL
  27716.             
  27717.                 select @at_publisher=0
  27718.                 if @publisher=@@SERVERNAME and @publisher_db=db_name()
  27719.                 begin
  27720.                     select @at_publisher=1
  27721.                     if @pubname like @publication_to_add or charindex('[' + @pubname + ']', @publication_to_add)>0
  27722.                     begin
  27723.                         select @schematext = 'exec sp_repladdcolumn ''' + @dest_object + ''',''' + @column + ''','+  QUOTENAME(@typetext) + ', ''' + @publication_to_add + ''', 1'  
  27724.                         select @schemaversion = schemaversion from sysmergeschemachange
  27725.                         if (@schemaversion is NULL)
  27726.                             set @schemaversion = 1
  27727.                         else
  27728.                             select @schemaversion = 1 + max(schemaversion) from sysmergeschemachange        
  27729.                         set @schemaguid = newid()
  27730.                         set @schematype = 11 /* alter table */
  27731.                         exec @retcode = sp_mergearticlecolumn @pubname, @artname, @column, 'add','true'
  27732.                         if @retcode<>0 or @@ERROR<>0
  27733.                             goto INNER_FAIL -- need to deallocate cursor for this loop.
  27734.                         exec @retcode=sp_MSinsertschemachange @pubid, @artid, @schemaversion, @schemaguid, @schematype, @schematext
  27735.                         if @@ERROR<>0 or @retcode<>0 
  27736.                             goto INNER_FAIL
  27737.                             
  27738.                         --insert a schema change for Jet specifically subscribers    
  27739.                         select @schematext = 'alter table ' +  @dest_object + ' add ' + @column + ' ' + @typetext
  27740.                         select @schemaversion = @schemaversion + 1
  27741.                         set @schematype = 13 -- for Jet use only
  27742.                         set @schemaguid = newid()
  27743.                         exec @retcode=sp_MSinsertschemachange @pubid, @artid, @schemaversion, @schemaguid, @schematype, @schematext                        
  27744.                         if @@ERROR<>0 or @retcode<>0 
  27745.                             goto INNER_FAIL
  27746.                     end
  27747.                 end
  27748.     
  27749.                 if @at_publisher=1
  27750.                 begin
  27751.                     exec @retcode = sp_MSpublicationview @pubname, 1
  27752.                     if @retcode<>0 or @@ERROR<>0
  27753.                         goto INNER_FAIL
  27754.                 end
  27755.  
  27756.                 select @columns_in_partition=count(*) from syscolumns where id = @sync_objid
  27757.                 if @columns_in_partition>246
  27758.                 begin
  27759.                     raiserror('Failed to add column ''%s'' to table ''%s'' because there are too many columns in the partition', 16, -1,@column, @source_object)
  27760.                     goto INNER_FAIL
  27761.                 end
  27762.             
  27763.                 exec @retcode = sp_MSdroparticletriggers @qual_source_object
  27764.                 if @retcode<>0 or @@ERROR<>0
  27765.                     goto INNER_FAIL
  27766.                 exec @retcode = sp_MSaddmergetriggers @qual_source_object
  27767.                 if @retcode<>0 or @@ERROR<>0
  27768.                     goto INNER_FAIL
  27769.  
  27770.                 /*
  27771.                 ** Force the regeneration of merge procs for all publications that publish the current table
  27772.                 */
  27773.                     
  27774.                 exec @retcode = sp_MSsetartprocs @publication=@pubname, @article=@artname, @force_flag=1
  27775.                 if @retcode<>0 or @@ERROR<>0
  27776.                     goto INNER_FAIL
  27777.         /*
  27778.         ** passing in one more parameter to sp_MSgetconflictinsertproc such that there is 
  27779.         ** no select statement at the end of that SP as needed else where. The default is 1.
  27780.         */
  27781.                 exec @retcode = sp_MSgetconflictinsertproc @artid, @pubid, 0
  27782.                 if @retcode<>0 or @@ERROR<>0
  27783.                     goto INNER_FAIL
  27784.  
  27785.                 fetch #addcolumn into @pubid, @artname, @sync_objid, @artid, @conflict_table, @ins_conflict_proc, @dest_owner
  27786.         END
  27787.         close #addcolumn
  27788.         deallocate #addcolumn
  27789.     
  27790.         declare @column_tracking int
  27791.         select @column_tracking=column_tracking, @nickname=nickname from sysmergearticles where objid=@objid
  27792.         if @column_tracking = 1
  27793.         begin
  27794.             --make sure there is no colv overflow, which was not caught by 246 column restriction because
  27795.             --users keep adding/dropping column, which causes no increase in number of coumns but consume
  27796.             --colv slot cause we never release the slot when a column is dropped
  27797.             if exists (select * from MSmerge_contents where tablenick=@nickname and len(colv1)>2040)
  27798.             begin                
  27799.                 raiserror(21418, 16, -1,@column, @source_object)
  27800.                 goto INNER_FAIL
  27801.             end
  27802.             --apend an lineage slot for the new column. 
  27803.             update MSmerge_contents set 
  27804.                 colv1=substring(colv1, 1, (datalength(colv1)-1)) + substring(colv1, 1, 4) + 0x01000000FF
  27805.                     where tablenick=@nickname
  27806.             if @@ERROR<>0
  27807.                 goto FAILURE
  27808.         end
  27809.     end
  27810.  
  27811.     if @is_for_tran = 1
  27812.     begin 
  27813.         declare #trancolumn CURSOR LOCAL FAST_FORWARD for 
  27814.             select a.artid, p.name from sysarticles a, syspublications p where a.objid=@objid
  27815.                 and p.pubid = a.pubid
  27816.                 and (p.name like @publication_to_add or charindex('[' + p.name + ']', @publication_to_add)>0)
  27817.         open #trancolumn
  27818.         fetch #trancolumn into @tran_artid, @pubname
  27819.         while (@@fetch_status <> -1)
  27820.         BEGIN
  27821.             select @artname = name, @tran_pubid = pubid, @owner = dest_owner, @tablename = dest_table from sysarticles where artid=@tran_artid
  27822.             exec @retcode = sp_articlecolumn @publication = @pubname, @article = @artname, @column = @column, 
  27823.                              @operation = 'add', @change_active = 2
  27824.                             ,@force_invalidate_snapshot = 1
  27825.                             ,@force_reinit_subscription = 1
  27826.             if @retcode <>0 or @@ERROR<>0
  27827.                 goto DROPTRAN
  27828.             if(@force_reinit_subscription = 0)    
  27829.             begin
  27830.                 if(@owner is not NULL) and (len(@owner) > 0)
  27831.                     select @qual_dest_object = QUOTENAME(@owner) + N'.' 
  27832.                 else 
  27833.                     select @qual_dest_object = N'' 
  27834.                 if(@tablename is not null) and (len(@tablename) > 0)
  27835.                     select @qual_dest_object = @qual_dest_object + QUOTENAME(@tablename)
  27836.                 else 
  27837.                     select @qual_dest_object = @qual_source_object
  27838.                 exec @retcode = sp_MSrepl_schema @pubname = @pubname 
  27839.                             ,@artid = @tran_artid
  27840.                             ,@qual_source_object = @qual_dest_object
  27841.                             ,@column = @column
  27842.                             ,@operation = 0 -- 0 is add, 1 is delete
  27843.                             ,@typetext = @typetext
  27844.                             ,@schema_change_script = @schema_change_script
  27845.                 if @retcode <>0 or @@ERROR<>0
  27846.                     goto DROPTRAN
  27847.             end
  27848.             exec @retcode = dbo.sp_MSreinit_article 
  27849.                             @publication = @pubname
  27850.                             ,@article = @artname
  27851.                             ,@need_new_snapshot = @force_invalidate_snapshot
  27852.                             ,@need_reinit_subscription = @force_reinit_subscription 
  27853.                             ,@force_invalidate_snapshot = @force_invalidate_snapshot
  27854.                             ,@force_reinit_subscription = @force_reinit_subscription
  27855.             if @retcode <>0 or @@ERROR<>0
  27856.                 goto DROPTRAN
  27857.             fetch #trancolumn into @tran_artid, @pubname            
  27858.         END
  27859.         close #trancolumn
  27860.         deallocate #trancolumn
  27861.          exec @retcode = sp_replincrementlsn @schema_end_lsn OUTPUT
  27862.          if @@ERROR<>0 or @retcode <> 0
  27863.              goto FAILURE
  27864.          if (@schema_start_lsn is not null) and (@schema_end_lsn is not null)
  27865.          begin
  27866.              insert systranschemas (tabid, startlsn, endlsn) values (@objid, @schema_start_lsn, @schema_end_lsn)
  27867.              if @@ERROR<>0
  27868.                  goto FAILURE
  27869.              exec @retcode = sp_replflush @objid, @schema_start_lsn, @schema_end_lsn
  27870.              if @@ERROR<>0 or @retcode <> 0
  27871.                  goto FAILURE
  27872.          end
  27873.          else
  27874.              goto FAILURE
  27875.     end
  27876.     
  27877.     /* Get back to its original replication state */
  27878.     if @is_for_merge=1
  27879.     begin
  27880.         exec @retcode = sp_MSmarkreplinfo @tablename, @owner
  27881.         if @retcode<>0 or @@ERROR<>0
  27882.             goto FAILURE
  27883.         update syscolumns set colstat = colstat | @merge_pub_markcolumn_bit where id=@objid and name= @column
  27884.         if @@ERROR<>0
  27885.             goto FAILURE
  27886.     end
  27887.  
  27888. COMMIT TRAN
  27889. return (0)
  27890.  
  27891. INNER_FAIL:
  27892. CLOSE #addcolumn
  27893. DEALLOCATE #addcolumn
  27894. GOTO FAILURE
  27895.  
  27896. ERROR_EXIT:
  27897. CLOSE #nosnapshot
  27898. DEALLOCATE #nosnapshot
  27899. GOTO FAILURE
  27900.  
  27901. DROPTRAN:
  27902. CLOSE #trancolumn
  27903. DEALLOCATE #trancolumn
  27904.  
  27905. FAILURE:
  27906.     rollback tran sp_repladdcolumn
  27907.     commit tran
  27908.     raiserror(21285, 16, -1, @column, @source_object)
  27909.     return (1)    
  27910. go
  27911.  
  27912. exec dbo.sp_MS_marksystemobject sp_repladdcolumn 
  27913. go
  27914. grant execute on dbo.sp_repladdcolumn to public
  27915. go
  27916. EXEC dbo.sp_MS_marksystemobject sp_MSget_jobstate
  27917. GO
  27918.  
  27919. exec dbo.sp_MS_marksystemobject sp_MSunc_to_drive
  27920. go
  27921.  
  27922. exec dbo.sp_MS_marksystemobject sp_MSrepl_isdbowner
  27923. go
  27924.  
  27925. dump tran master with no_log
  27926. go
  27927.  
  27928. raiserror('Creating procedure sp_MSagent_access_check',0,1)
  27929. go
  27930. CREATE PROCEDURE sp_MSagent_access_check (
  27931.     @job_id         VARBINARY(16),
  27932.     @agent_type     sysname = NULL -- 'distribution' or 'merge', case insensitive
  27933. ) AS
  27934.  
  27935.     DECLARE @retcode int
  27936.     DECLARE @count   int
  27937.  
  27938.     IF @agent_type IS NOT NULL
  27939.     BEGIN
  27940.         IF LOWER(@agent_type collate SQL_Latin1_General_CP1_CS_AS) NOT IN (N'distribution', N'merge')
  27941.         BEGIN
  27942.             RAISERROR(21170, 16, -1)
  27943.             RETURN (1)
  27944.         END
  27945.     END
  27946.  
  27947.     SELECT @retcode = 0
  27948.     -- Create a list of owners of the subscriptions depending on the given 
  27949.     -- agent 
  27950.     CREATE TABLE #sub_owner_list (owner_name sysname collate database_default)
  27951.  
  27952.     -- Try querying the Transactional subscriptions for the owner 
  27953.     IF @agent_type IS NULL OR LOWER(@agent_type collate SQL_Latin1_General_CP1_CS_AS) = N'distribution'
  27954.     BEGIN
  27955.  
  27956.         IF EXISTS (SELECT * 
  27957.                      FROM sysobjects 
  27958.                     WHERE type in ('U', 'S') AND name = N'syssubscriptions')
  27959.         BEGIN
  27960.             INSERT INTO #sub_owner_list 
  27961.             SELECT DISTINCT login_name 
  27962.               FROM dbo.syssubscriptions 
  27963.              WHERE distribution_jobid = @job_id 
  27964.         END
  27965.  
  27966.         IF NOT EXISTS (SELECT * FROM #sub_owner_list) AND 
  27967.            @agent_type IS NOT NULL
  27968.         BEGIN
  27969.             RAISERROR(21167, 16, -1, 'Distribution')
  27970.             SELECT @retcode = 1
  27971.             GOTO FAILURE
  27972.         END 
  27973.     END
  27974.  
  27975.     IF (@agent_type IS NULL AND NOT EXISTS (SELECT * FROM #sub_owner_list)) OR
  27976.        LOWER(@agent_type collate SQL_Latin1_General_CP1_CS_AS) = N'merge' 
  27977.     BEGIN
  27978.         
  27979.         SELECT @count = COUNT(*)
  27980.           FROM sysobjects
  27981.          WHERE name IN (N'sysmergesubscriptions', N'MSmerge_replinfo')
  27982.         
  27983.         IF @count = 2        
  27984.         BEGIN
  27985.             INSERT INTO #sub_owner_list 
  27986.             SELECT DISTINCT sms.login_name 
  27987.               FROM dbo.MSmerge_replinfo mr
  27988.         INNER JOIN dbo.sysmergesubscriptions sms
  27989.                 ON mr.repid = sms.subid
  27990.              WHERE mr.merge_jobid = @job_id
  27991.         END
  27992.  
  27993.         IF NOT EXISTS (SELECT * FROM #sub_owner_list) AND 
  27994.            @agent_type IS NOT NULL
  27995.         BEGIN
  27996.             RAISERROR(21167, 16, -1, 'Merge')
  27997.             SELECT @retcode = 1
  27998.             GOTO FAILURE
  27999.         END 
  28000.     END
  28001.  
  28002.     IF NOT EXISTS (SELECT * FROM #sub_owner_list) 
  28003.     BEGIN
  28004.         RAISERROR(21134, 16, -1)
  28005.         SELECT @retcode = 1
  28006.         GOTO FAILURE
  28007.     END
  28008.  
  28009.     IF suser_sname(suser_sid()) NOT IN (SELECT owner_name FROM #sub_owner_list) AND
  28010.        is_srvrolemember('sysadmin') <> 1 AND
  28011.        is_member('db_owner') <> 1
  28012.     BEGIN
  28013.  
  28014.         RAISERROR(21168, 16, -1)
  28015.         SELECT @retcode = 1
  28016.         GOTO FAILURE
  28017.     END
  28018.  
  28019. FAILURE:
  28020.  
  28021.     DROP TABLE #sub_owner_list
  28022.     RETURN @retcode
  28023.  
  28024. GO
  28025.  
  28026. EXEC dbo.sp_MS_marksystemobject sp_MSagent_access_check
  28027. GO
  28028.  
  28029. raiserror('Creating procedure sp_enableagentoffload',0,1)
  28030. go
  28031. CREATE PROCEDURE sp_enableagentoffload (
  28032.     @job_id         VARBINARY(16),
  28033.     @offloadserver  sysname = NULL,
  28034.     @agent_type     sysname = NULL -- 'distribution' or 'merge', case insensitive
  28035.     ) AS
  28036.     SET NOCOUNT ON
  28037.     DECLARE @retcode        INT
  28038.     DECLARE @distributor    sysname
  28039.     DECLARE @distributiondb sysname
  28040.     DECLARE @distproc       NVARCHAR(300)
  28041.  
  28042.     SELECT @retcode = 0
  28043.     SELECT @distributor    = NULL
  28044.     SELECT @distributiondb = NULL
  28045.  
  28046.     EXEC @retcode = sp_MSreplcheckoffloadserver @offloadserver
  28047.     IF @retcode<>0 OR @@error<>0
  28048.         RETURN (1)
  28049.  
  28050.     EXEC @retcode = sp_MSagent_access_check @job_id = @job_id, 
  28051.                                             @agent_type = @agent_type
  28052.  
  28053.     IF @retcode <> 0
  28054.         RETURN @retcode        
  28055.  
  28056.     EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  28057.                                            @distribdb = @distributiondb OUTPUT
  28058.     IF @retcode <> 0
  28059.         RETURN @retcode
  28060.  
  28061.     SELECT @distributor = RTRIM(@distributor)
  28062.  
  28063.     IF LOWER(@@SERVERNAME) <> LOWER(@distributor)
  28064.     BEGIN 
  28065.         SELECT @distproc = @distributor + '.' + @distributiondb + 
  28066.                            '.dbo.sp_MSenableagentoffload'
  28067.     END
  28068.     ELSE
  28069.     BEGIN
  28070.         SELECT @distproc = @distributiondb + '.dbo.sp_MSenableagentoffload'
  28071.     END
  28072.  
  28073.     EXECUTE @retcode = @distproc 
  28074.                 @job_id = @job_id,
  28075.                 @offloadserver = @offloadserver
  28076.  
  28077.     RETURN @retcode
  28078. GO
  28079. EXEC dbo.sp_MS_marksystemobject sp_enableagentoffload
  28080. GO
  28081.  
  28082. print ''
  28083. print 'Creating procedure sp_disableagentoffload'
  28084. go
  28085. CREATE PROCEDURE sp_disableagentoffload (
  28086.     @job_id         VARBINARY(16),
  28087.     @offloadserver  sysname = NULL,
  28088.     @agent_type     sysname = NULL -- 'distribution' or 'merge', case insensitive
  28089. ) AS
  28090.     SET NOCOUNT ON
  28091.     DECLARE @retcode        INT
  28092.     DECLARE @distributor    sysname
  28093.     DECLARE @distributiondb sysname
  28094.     DECLARE @distproc       NVARCHAR(300)
  28095.  
  28096.     SELECT @retcode = 0
  28097.     SELECT @distributor    = NULL
  28098.     SELECT @distributiondb = NULL
  28099.  
  28100.     EXEC @retcode = sp_MSagent_access_check @job_id = @job_id, 
  28101.                                             @agent_type = @agent_type
  28102.  
  28103.     IF @retcode <> 0
  28104.         RETURN @retcode        
  28105.     
  28106.     EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  28107.                                            @distribdb = @distributiondb OUTPUT
  28108.  
  28109.     IF @retcode <> 0
  28110.         RETURN @retcode
  28111.  
  28112.     SELECT @distributor = RTRIM(@distributor)
  28113.  
  28114.     IF LOWER(@@SERVERNAME) <> LOWER(@distributor)
  28115.     BEGIN 
  28116.         SELECT @distproc = @distributor + '.' + @distributiondb + 
  28117.                            '.dbo.sp_MSdisableagentoffload'
  28118.     END
  28119.     ELSE
  28120.     BEGIN
  28121.         SELECT @distproc = @distributiondb + '.dbo.sp_MSdisableagentoffload'
  28122.     END
  28123.  
  28124.     EXECUTE @retcode = @distproc 
  28125.                 @job_id = @job_id,
  28126.                 @offloadserver = @offloadserver
  28127.  
  28128.     RETURN @retcode
  28129. GO
  28130. EXEC dbo.sp_MS_marksystemobject sp_disableagentoffload
  28131. GO
  28132.  
  28133. print ''
  28134. print 'Creating procedure sp_getagentoffloadinfo'
  28135. go
  28136. CREATE PROCEDURE sp_getagentoffloadinfo (
  28137.     @job_id         VARBINARY(16)
  28138. ) AS
  28139.     SET NOCOUNT ON
  28140.     DECLARE @retcode        INT
  28141.     DECLARE @distributor    sysname
  28142.     DECLARE @distributiondb sysname
  28143.     DECLARE @distproc       NVARCHAR(300)
  28144.  
  28145.     SELECT @retcode = 0
  28146.     SELECT @distributor    = NULL
  28147.     SELECT @distributiondb = NULL
  28148.  
  28149.     -- security check, db_owner
  28150.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  28151.     IF @@ERROR <> 0 or @retcode <> 0
  28152.         return (1)
  28153.  
  28154.  
  28155.     EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  28156.                                            @distribdb = @distributiondb OUTPUT
  28157.  
  28158.     IF @retcode <> 0
  28159.         RETURN @retcode
  28160.  
  28161.     SELECT @distributor = RTRIM(@distributor)
  28162.  
  28163.     SELECT @distproc = @distributor + '.' + @distributiondb + 
  28164.                            '.dbo.sp_MSgetagentoffloadinfo'
  28165.  
  28166.     EXECUTE @retcode = @distproc 
  28167.                 @job_id = @job_id
  28168.  
  28169.     RETURN @retcode
  28170. GO
  28171. EXEC dbo.sp_MS_marksystemobject sp_getagentoffloadinfo
  28172. GO
  28173.  
  28174. print ''
  28175. print 'Creating procedure sp_copysubscription'
  28176. go
  28177. CREATE PROCEDURE sp_copysubscription (
  28178. @filename nvarchar(260),
  28179. @temp_dir nvarchar(260) = NULL,
  28180. -- Directory contains temp files. If not specified, SQL
  28181. -- server default data directory will be used.
  28182. @overwrite_existing_file bit = 0
  28183. )
  28184. AS
  28185.  
  28186.     SET NOCOUNT ON
  28187.  
  28188.     /*
  28189.     ** Declarations.
  28190.     */
  28191.     declare @cmd nvarchar(4000)
  28192.     declare @retcode int
  28193.     declare @data_path nvarchar(260)
  28194.     declare @subscriber_srvid     int
  28195.     declare @subscriber_db        sysname
  28196.     declare @backup_path nvarchar(260)
  28197.     declare @temp_data_path nvarchar(260)
  28198.     declare @temp_log_path nvarchar(260)
  28199.     declare @retention            int
  28200.     declare @retention_date       datetime
  28201.     declare @pubid                 uniqueidentifier
  28202.  
  28203.  
  28204.     /*
  28205.     * Initializations
  28206.     */
  28207.     select @retcode = 0
  28208.     select @subscriber_srvid = 0
  28209.     select @subscriber_db = db_name()
  28210.  
  28211.     -- We only support single file attach. Check to make sure
  28212.     -- there are only 2 files, one data file and one log file
  28213.     if (select count(*) from sysfiles) > 2
  28214.     begin
  28215.         raiserror(21212,16, -1)
  28216.         return 1
  28217.     end
  28218.  
  28219.     /* Make sure all tran sub allows attach */
  28220.     declare @publication                 sysname
  28221.     declare @publisher                    sysname
  28222.     declare @tran_found                    bit
  28223.     declare @merge_found                bit
  28224.     select @tran_found = 0
  28225.     select @merge_found = 0
  28226.  
  28227.     /* 
  28228.     ** Make sure all merge subscriptions in the current database 
  28229.     ** have allow_subscription_copy set to TRUE
  28230.     ** and there are no push subscriptions. 
  28231.     */
  28232.     if exists (select * from sysobjects where name = 'MSsubscription_agents')
  28233.     begin
  28234.         set @publisher = NULL
  28235.         -- Not using @publication because share agent case.
  28236.         select top 1 @publisher = publisher from MSsubscription_agents where
  28237.             allow_subscription_copy = 0
  28238.         IF @publisher is not null
  28239.         BEGIN
  28240.             RAISERROR(21236, 16, -1, @publisher)
  28241.             RETURN (1)
  28242.         END
  28243.  
  28244.         set @publisher = null
  28245.         select top 1 @publisher = publisher from MSreplication_subscriptions where
  28246.             subscription_type = 0
  28247.         IF @publisher is not null
  28248.         BEGIN
  28249.             RAISERROR(21237, 16, -1, @publisher)            
  28250.             RETURN (1)
  28251.         END
  28252.         if exists (select * from MSsubscription_agents)
  28253.             select @tran_found = 1
  28254.     end            
  28255.  
  28256.     /* 
  28257.     ** Make sure all merge subscriptions in the current database 
  28258.     ** have allow_subscription_copy set to TRUE
  28259.     ** and there are no push subscriptions. 
  28260.     */
  28261.     if exists (select * from sysobjects where name = 'sysmergepublications')
  28262.         begin
  28263.             set @publication = NULL
  28264.             select top 1 @publication = name from sysmergepublications where
  28265.                 allow_subscription_copy = 0
  28266.             IF @publication is not null
  28267.                 BEGIN
  28268.                     RAISERROR (21204, 16, -1, @publication)    
  28269.                     RETURN (1)
  28270.                 END
  28271.  
  28272.             set @publication = null
  28273.             select top 1 @publication = p.name from sysmergepublications p, 
  28274.                 sysmergesubscriptions s where
  28275.                 p.pubid = s.pubid and
  28276.                 s.subid <> s.pubid and 
  28277.                 db_name = db_name() collate database_default and 
  28278.                 subscriber_server = convert(nvarchar(4000), SERVERPROPERTY('ServerName')) collate database_default  and
  28279.                 s.subscription_type = 0
  28280.             IF @publication is not null
  28281.             BEGIN
  28282.                 RAISERROR(21238, 16, -1, @publication)            
  28283.                 RETURN (1)
  28284.             END
  28285.  
  28286.             -- Does db contains subscriptions?
  28287.             if exists (select * from sysmergesubscriptions where subid <> pubid and 
  28288.                 db_name = db_name() collate database_default and 
  28289.                 subscriber_server = convert(nvarchar(4000), SERVERPROPERTY('ServerName')) collate database_default)
  28290.                 select @merge_found = 1
  28291.  
  28292.             /* Retention check : Make sure that the subscription copy is not too old */
  28293.             declare PC CURSOR LOCAL FAST_FORWARD for select DISTINCT p.name, p.pubid, p.retention from sysmergepublications p, sysmergesubscriptions s 
  28294.                 where s.subid=p.pubid and s.pubid=p.pubid for read only
  28295.             open PC
  28296.             fetch PC into @publication, @pubid, @retention 
  28297.             
  28298.             WHILE (@@fetch_status <> -1)
  28299.                 BEGIN
  28300.                     /* Compute the retention period cutoff dates per publication */
  28301.                     select @retention_date = dateadd(day, -@retention, getdate())
  28302.                        if @retention is not NULL and @retention > 0
  28303.                     begin
  28304.                         if not exists (select coldate from sysmergearticles , MSmerge_genhistory 
  28305.                                             where    nickname = art_nick 
  28306.                                                     and coldate > @retention_date 
  28307.                                                     and sysmergearticles.pubid = @pubid)
  28308.                             begin
  28309.                                 RAISERROR (21306, 16, -1, @publication)
  28310.                                 return (1)
  28311.                             end                                
  28312.                     end
  28313.                     fetch PC into @publication, @pubid, @retention
  28314.                 END
  28315.  
  28316.         end            
  28317.  
  28318.     if @tran_found = 0 and @merge_found = 0
  28319.     begin
  28320.         raiserror(21239, 16 , -1)
  28321.         return (1)
  28322.     end
  28323.     
  28324.     -- Security check
  28325.     -- Only DBO or sysadmin can do this
  28326.     -- The user also must have create db permissions.
  28327.     exec @retcode = dbo.sp_MSreplcheck_subscribe
  28328.     IF @retcode <> 0 or @@error <> 0
  28329.         return 1
  28330.  
  28331.     if @overwrite_existing_file is null
  28332.         set @overwrite_existing_file = 0
  28333.  
  28334.     -- Check to see if the file already exists
  28335.     declare @exists bit
  28336.  
  28337.     if @overwrite_existing_file = 0
  28338.     begin
  28339.         exec @retcode = dbo.sp_MSget_file_existence @filename, @exists output
  28340.         if @@error <> 0 or @retcode <> 0
  28341.             return 1
  28342.         if @exists <> 0 
  28343.         begin
  28344.             raiserror(21214, 16, -1, @filename)
  28345.             return 1
  28346.         end
  28347.     end
  28348.  
  28349.     -- Check to see if have write permissions to the file location.
  28350.     -- Try create the file
  28351.     -- Echo text can be anything.
  28352.     select @cmd = 'echo Subscription copy failed. > "' + fn_escapecmdshellsymbolsremovequotes(@filename) collate database_default + '"'
  28353.     exec @retcode = master.dbo.xp_cmdshell @cmd, NO_OUTPUT
  28354.     if @@error <> 0 or @retcode <> 0
  28355.     begin
  28356.         raiserror(21247, 16, -1, @filename)
  28357.         select @retcode = 1
  28358.         goto Cleanup
  28359.     end    
  28360.     -- File should be created.
  28361.     exec @retcode = dbo.sp_MSget_file_existence @filename, @exists output
  28362.     if @@error <> 0 or @retcode <> 0
  28363.     begin
  28364.         select @retcode = 1
  28365.         goto Cleanup
  28366.     end
  28367.     if @exists = 0
  28368.     begin
  28369.         raiserror(21247,16, -1, @filename)
  28370.         select @retcode = 1
  28371.         goto Cleanup
  28372.     end
  28373.  
  28374.     /*
  28375.     ** Get the MSSQL DATA path. Note that users can have a SQLDataRoot directory different from SQLPath
  28376.     */
  28377.     if @temp_dir is null
  28378.     begin
  28379.         exec @retcode = master.dbo.sp_MSget_setup_paths
  28380.             @data_path = @temp_dir output
  28381.         IF @retcode <> 0 or @@error <> 0
  28382.             return 1
  28383.         select @temp_dir = @temp_dir + '\DATA\'
  28384.     end
  28385.     else
  28386.     begin
  28387.         -- Check to make sure working dir is valid.
  28388.         exec @retcode = dbo.sp_MSget_file_existence @temp_dir, @exists output
  28389.         if @@error <> 0 or @retcode <> 0
  28390.         begin
  28391.             select @retcode = 1
  28392.             goto Cleanup
  28393.         end
  28394.         if @exists = 0
  28395.         begin
  28396.             raiserror (21037, 16, -1, @temp_dir)        
  28397.             select @retcode = 1
  28398.             goto Cleanup
  28399.         end
  28400.         if substring(@temp_dir, len(@temp_dir), 1) <> '\'
  28401.             select @temp_dir = @temp_dir + '\'
  28402.     end
  28403.  
  28404.     -- Get temp db name
  28405.     -- Use a guid to avoid name colision.
  28406.     declare @dbname sysname
  28407.     select @dbname = db_name()
  28408.     declare @temp_db_name sysname
  28409.     declare @guid_name nvarchar(36)
  28410.     select @guid_name =  convert (nvarchar(36), newid())
  28411.  
  28412.     select @temp_db_name = 'repl_sub_restore_' + @guid_name
  28413.  
  28414.     select @backup_path = @temp_dir + @temp_db_name + '.bak'
  28415.  
  28416.     -- Create table used to signal attach or restored process to do different things
  28417.     if not exists (select * from sysobjects where name = 'MSreplication_restore_stage')
  28418.     begin 
  28419.         CREATE TABLE dbo.MSreplication_restore_stage
  28420.         (
  28421.         stage_id int -- not used for now
  28422.         )
  28423.         IF @@ERROR <> 0
  28424.             return 1
  28425.     end
  28426.     
  28427.     -- First backup the database to the file given
  28428.     -- Overwrite the existing file with INIT option.
  28429.     BACKUP DATABASE @dbname TO DISK = @backup_path WITH INIT
  28430.     if @@error<> 0
  28431.     begin
  28432.         select @retcode = 1
  28433.         goto Cleanup
  28434.     end
  28435.  
  28436.  
  28437.     -- Restore it to a temporary working database
  28438.     -- Get phy data and log file name for the temp db
  28439.     select @temp_data_path = @temp_dir + @temp_db_name + '.mdf'
  28440.     select @temp_log_path = @temp_dir + @temp_db_name + '.ldf'
  28441.  
  28442.     -- Get the command
  28443.     select @cmd = 'restore database ' + quotename(@temp_db_name) + ' from disk = ' 
  28444.         + quotename(@backup_path,'''') + ' with replace, move '
  28445.  
  28446.     -- Get the logical file name for data file.
  28447.     select @cmd = @cmd + quotename(rtrim(name),'''') from sysfiles where
  28448.         (status & 0x40) = 0
  28449.  
  28450.     -- Use passed in filename as phy data file name for the temp db
  28451.  
  28452.     -- Use the passed in file as phy data file for the temp db
  28453.     select @cmd = @cmd + ' to ' + quotename(@temp_data_path,'''') + ', move '
  28454.  
  28455.     -- Get the logical file name for the log file
  28456.     select @cmd = @cmd + quotename(rtrim(name),'''') from sysfiles where
  28457.         (status & 0x40) <> 0
  28458.  
  28459.     -- Use the passed in file as phy file for the temp db
  28460.     select @cmd = @cmd + ' to ' + quotename(@temp_log_path,'''') + ' '
  28461.     exec (@cmd)
  28462.     if @@error<> 0
  28463.     begin
  28464.         select @retcode = 1
  28465.         goto Cleanup
  28466.     end
  28467.  
  28468.     -- Once we successfully restored, we delete to back up file to save disk space.
  28469.     if @backup_path is not null
  28470.     begin
  28471.         select @cmd = 'del "' + fn_escapecmdshellsymbolsremovequotes(@backup_path) collate database_default + '"' 
  28472.         EXEC master..xp_cmdshell @cmd, NO_OUTPUT
  28473.         set @backup_path = null
  28474.     end
  28475.  
  28476.     -- Prepare the database for detach. 2 things will be done
  28477.     -- 1. Set a flag to indicate that this is a prepare sub db for detach
  28478.     -- 2. For merge, create table to store sysservers info for later fixing up after attach
  28479.     select @cmd = quotename(@temp_db_name) + '.dbo.sp_MSprepare_sub_for_detach'
  28480.     
  28481.     exec @retcode = @cmd @subscriber_srvid = @subscriber_srvid, @subscriber_db = @subscriber_db
  28482.     if @retcode<>0 or @@error<>0
  28483.     begin
  28484.         select @retcode = 1
  28485.         goto Cleanup
  28486.     end
  28487.  
  28488.     -- Shink the size of the temp db before detach
  28489.     DBCC SHRINKDATABASE (@temp_db_name, 10)
  28490.     if @@error <> 0
  28491.         goto Cleanup
  28492.  
  28493.     -- detach the database
  28494.     -- Wait for the db to be closed
  28495.     WAITFOR DELAY '00:00:00.500'
  28496.     exec @retcode = sp_detach_db @temp_db_name
  28497.     if @retcode<>0 or @@error<>0
  28498.     begin
  28499.         select @retcode = 1
  28500.         goto Cleanup
  28501.     end
  28502.  
  28503.     -- Delete the log file to save disk space
  28504.     if @temp_log_path is not null
  28505.     begin
  28506.         select @cmd = 'del "' + fn_escapecmdshellsymbolsremovequotes(@temp_log_path) collate database_default + '"' 
  28507.         EXEC master..xp_cmdshell @cmd, NO_OUTPUT
  28508.         set @temp_log_path = null
  28509.     end
  28510.  
  28511.     -- Compress the file
  28512.     exec @retcode = master..xp_makecab
  28513.         @cabfilename = @filename,
  28514.         @compression_mode ='mszip',
  28515.         @verbose_level = 0,
  28516.         @filename1 = @temp_data_path
  28517.     if @retcode<>0 or @@error<>0
  28518.     begin
  28519.         select @retcode = 1
  28520.         goto Cleanup
  28521.     end
  28522.  
  28523.  
  28524. Cleanup:
  28525.     if exists (select * from sysobjects where name = 'MSreplication_restore_stage')
  28526.         drop table dbo.MSreplication_restore_stage
  28527.  
  28528.  
  28529.     if exists (select * from master..sysdatabases where name = @temp_db_name collate database_default)
  28530.     begin
  28531.         select @cmd = 'drop database ' + quotename(@temp_db_name)
  28532.         exec (@cmd)
  28533.     end
  28534.  
  28535.     if @backup_path is not null
  28536.     begin
  28537.         select @cmd = 'del "' + fn_escapecmdshellsymbolsremovequotes(@backup_path) collate database_default + '"' 
  28538.         EXEC master..xp_cmdshell @cmd, NO_OUTPUT
  28539.     end
  28540.  
  28541.     if @temp_data_path is not null
  28542.     begin
  28543.         select @cmd = 'del "' + fn_escapecmdshellsymbolsremovequotes(@temp_data_path) collate database_default + '"' 
  28544.         EXEC master..xp_cmdshell @cmd, NO_OUTPUT
  28545.     end
  28546.  
  28547.     if @temp_log_path is not null
  28548.     begin
  28549.         select @cmd = 'del "' + fn_escapecmdshellsymbolsremovequotes(@temp_log_path) collate database_default + '"' 
  28550.         EXEC master..xp_cmdshell @cmd, NO_OUTPUT
  28551.     end
  28552.  
  28553.     if @retcode <> 0
  28554.     begin
  28555.         select @cmd = 'del "' + fn_escapecmdshellsymbolsremovequotes(@filename) collate database_default + '"' 
  28556.         EXEC master..xp_cmdshell @cmd, NO_OUTPUT
  28557.     end
  28558.  
  28559.     return @retcode
  28560. go
  28561. EXEC dbo.sp_MS_marksystemobject sp_copysubscription
  28562. GO
  28563.  
  28564. print ''
  28565. print 'Creating procedure sp_attachsubscription'
  28566. go
  28567. CREATE PROCEDURE sp_attachsubscription (
  28568. @dbname    sysname,
  28569. @filename nvarchar(260),
  28570. @subscriber_security_mode        int = NULL,                        /* 0 standard; 1 integrated */
  28571. @subscriber_login                sysname = NULL,
  28572. @subscriber_password            sysname = NULL
  28573. )
  28574. AS
  28575.  
  28576.     SET NOCOUNT ON
  28577.  
  28578.     /*
  28579.     ** Declarations.
  28580.     */
  28581.     declare @cmd nvarchar(4000)
  28582.     declare @retcode int
  28583.     DECLARE @platform_nt binary
  28584.     declare @copy_created bit
  28585.     declare @exists bit
  28586.  
  28587.     select @platform_nt = 0x1    
  28588.     select @retcode = 0
  28589.     select @copy_created = 0
  28590.     select @exists = 0
  28591.  
  28592.     -- Parameter check: @subscriber_security_mode
  28593.     if @subscriber_security_mode is null
  28594.     begin
  28595.         if ( platform() & @platform_nt ) = @platform_nt
  28596.             select @subscriber_security_mode = 1
  28597.         else
  28598.             select @subscriber_security_mode = 0
  28599.     end    
  28600.  
  28601.     if ( ( platform() & @platform_nt ) <> @platform_nt and @subscriber_security_mode = 1 )
  28602.     begin
  28603.         RAISERROR(21038, 16, -1)
  28604.         RETURN (1)
  28605.     end
  28606.  
  28607.     if (@subscriber_security_mode = 0) and (@subscriber_login IS NULL or rtrim(@subscriber_login) = '')
  28608.         set @subscriber_login = 'sa'
  28609.  
  28610.     -- Check to make sure the database does not exists.
  28611.     if exists (select * from master..sysdatabases where name = @dbname collate database_default)
  28612.     begin
  28613.         raiserror(20621, 16, -1, @dbname)
  28614.         return (1)
  28615.     end
  28616.  
  28617.     -- Check to see if users has permissions to create database
  28618.     -- permissions() have to be run in master to return create db permission.
  28619.     declare @pm int
  28620.     exec @retcode = master.dbo.sp_executesql N'select @pm = permissions()', N'@pm int output', @pm output
  28621.     if @@error <> 0 or @retcode <> 0
  28622.         return 1
  28623.     if @pm & 1 = 0
  28624.     begin
  28625.         raiserror(20618, 16, -1)
  28626.         return 1
  28627.     end
  28628.  
  28629.     -- Decompress the file
  28630.     -- We have to copy the file to another location first. 
  28631.     -- (cannot use source as destination')
  28632.     declare @temp_copy nvarchar(260)
  28633.     declare @file_dir nvarchar(260)
  28634.     declare @file_name nvarchar(260)
  28635.     declare @dir_cmd nvarchar(260)
  28636.     -- Set @drive_cmd if needed 
  28637.     -- Set temp copy to be the file directory first
  28638.     -- Note @file_dir include '\'
  28639.     if (charindex('\', @filename, 1) = 0)
  28640.     begin
  28641.         select @file_dir = ''
  28642.         select @file_name = @filename
  28643.     end
  28644.     else
  28645.     begin
  28646.         select @file_dir = left(@filename,len(@filename) + 1 - 
  28647.             charindex('\', reverse(@filename), 1))
  28648.         select @file_name = right(@filename, len(@filename) - len(@file_dir))
  28649.     end
  28650.     -- Get guid name
  28651.     declare @guid_name nvarchar(36)
  28652.     select @guid_name =  convert (nvarchar(36), newid())
  28653.     select @temp_copy = @file_dir + @guid_name + '.tmp'
  28654.  
  28655.  
  28656.     -- copy file
  28657.     select @cmd = 'copy "' + fn_escapecmdshellsymbolsremovequotes(@filename) collate database_default + '" "' + fn_escapecmdshellsymbolsremovequotes(@temp_copy) collate database_default + '"'
  28658.     exec @retcode = master.dbo.xp_cmdshell @cmd, NO_OUTPUT
  28659.     if @@error <> 0 or @retcode <> 0
  28660.     begin
  28661.         raiserror(21248, 16, -1, @filename)
  28662.         select @retcode = 1
  28663.         goto Cleanup
  28664.     end    
  28665.  
  28666.     exec @retcode = dbo.sp_MSget_file_existence @temp_copy, @exists output
  28667.     if @@error <> 0 or @retcode <> 0
  28668.     begin
  28669.         select @retcode = 1
  28670.         goto Cleanup
  28671.     end
  28672.     if @exists = 0
  28673.     begin
  28674.         raiserror(21247, 16, -1, @temp_copy)        
  28675.         select @retcode = 1
  28676.         goto Cleanup
  28677.     end
  28678.  
  28679.     select @copy_created = 1
  28680.  
  28681.     -- decompress
  28682.     exec @retcode = master.dbo.xp_unpackcab 
  28683.         @cabfilename = @temp_copy,
  28684.         @destination_folder = @file_dir,
  28685.         @verbose_level = 0,
  28686.         @destination_file = @file_name,
  28687.         @suppress_messages = 1
  28688.         
  28689.     if @@error <> 0 
  28690.     begin
  28691.         select @retcode = 1
  28692.         goto Cleanup
  28693.     end
  28694.  
  28695.     if @retcode in (1030,1029,2005)
  28696.     begin
  28697.         raiserror(20609, 16, -1, @filename)
  28698.         select @retcode = 1
  28699.         goto Cleanup
  28700.     end    
  28701.     else if @retcode <> 0
  28702.     -- re-issue the command to get errors
  28703.     begin
  28704.         exec @retcode = master.dbo.xp_unpackcab 
  28705.             @cabfilename = @temp_copy,
  28706.             @destination_folder = @file_dir,
  28707.             @verbose_level = 0,
  28708.             @destination_file = @file_name,
  28709.             @suppress_messages = 0
  28710.         select @retcode = 1
  28711.         goto Cleanup
  28712.     end
  28713.  
  28714.     -- Attach
  28715.     exec @retcode = dbo.sp_attach_single_file_db
  28716.         @dbname = @dbname,
  28717.         @physname = @filename
  28718.     if @retcode<>0 or @@error<>0
  28719.     begin
  28720.         raiserror(21248, 16, -1, @filename)
  28721.         select @retcode = 1
  28722.         goto Cleanup
  28723.     end
  28724.  
  28725.     if isnull(is_srvrolemember('sysadmin'), 0) <> 0
  28726.     begin
  28727.         select @cmd = quotename(@dbname) + '.dbo.sp_changedbowner'
  28728.         exec @retcode = @cmd N'sa'
  28729.         if @retcode<>0 or @@error<>0
  28730.         begin
  28731.             select @retcode = 1
  28732.             goto Cleanup
  28733.         end
  28734.     end
  28735.  
  28736.     -- Prepare the database for detach. 2 things will be done
  28737.     -- 1. Set a flag to indicate that this is a prepare sub db for detach
  28738.     -- 2. For merge, create table to store sysservers info for later fixing up after attach
  28739.     select @cmd = quotename(@dbname) + '.dbo.sp_MSrestore_sub'
  28740.     exec @retcode = @cmd
  28741.         @subscriber_security_mode = @subscriber_security_mode,    
  28742.         @subscriber_login = @subscriber_login,
  28743.         @subscriber_password = @subscriber_password
  28744.     if @retcode<>0 or @@error<>0
  28745.     begin
  28746.         select @retcode = 1
  28747.         goto Cleanup
  28748.     end
  28749.  
  28750. Cleanup:
  28751.     if @retcode <> 0
  28752.     begin
  28753.         -- The files will be deleted if some thing failed. 
  28754.         if exists (select * from master..sysdatabases where name = @dbname collate database_default)
  28755.             begin
  28756.                 select @cmd = 'drop database ' + quotename(@dbname)
  28757.                 exec (@cmd)
  28758.             end                
  28759.     end
  28760.  
  28761.     if @temp_copy is not null
  28762.     begin
  28763.         -- Restore the original file, ignore errors
  28764.         if @retcode <> 0 and @copy_created = 1
  28765.         begin
  28766.             select @cmd = 'copy "' + fn_escapecmdshellsymbolsremovequotes(@temp_copy) collate database_default + '" "' + fn_escapecmdshellsymbolsremovequotes(@filename) collate database_default + '"'
  28767.             exec master.dbo.xp_cmdshell @cmd, NO_OUTPUT
  28768.         end
  28769.  
  28770.         -- Delete the temp file.
  28771.         select @cmd = 'del "' + fn_escapecmdshellsymbolsremovequotes(@temp_copy) collate database_default+ '"' 
  28772.         EXEC master..xp_cmdshell @cmd, NO_OUTPUT
  28773.     end
  28774.  
  28775.     return @retcode
  28776. go
  28777. EXEC dbo.sp_MS_marksystemobject sp_attachsubscription
  28778. GO
  28779.  
  28780.  
  28781. print ''
  28782. print 'Creating procedure sp_MSrestore_sub_merge'
  28783. go
  28784. CREATE PROCEDURE sp_MSrestore_sub_merge (
  28785.     @subscriber_security_mode        int,                        
  28786.     @subscriber_login                sysname,
  28787.     @subscriber_password            nvarchar(524)
  28788.     )
  28789. AS
  28790.  
  28791.     SET NOCOUNT ON
  28792.     declare @retcode             int
  28793.     declare @detached             int
  28794.     declare @attached             int
  28795.     DECLARE @publisher             sysname        /* Expression used in the cursor */
  28796.     DECLARE @publisher_db         sysname     /* Expression used in the cursor */
  28797.     DECLARE @publication         sysname      /* Expression used in the cursor */
  28798.     DECLARE @distributor        sysname        /* Expression used in the cursor */
  28799.     declare @subnickname        int
  28800.     declare @subid                 uniqueidentifier
  28801.     declare @detached_subid        uniqueidentifier
  28802.     declare @subscriber_srvid     int
  28803.     declare @subscriber_server    sysname
  28804.     declare @subscriber_db        sysname
  28805.     declare @enabled_for_syncmgr_int     int
  28806.     declare @enabled_for_syncmgr nvarchar(5)
  28807.     declare @retention            int
  28808.     declare @retention_date       datetime
  28809.     declare @pubid                 uniqueidentifier
  28810.     declare    @distributor_security_mode    int                        
  28811.     declare @distributor_login            sysname
  28812.     declare @distributor_password        nvarchar(524)
  28813.     declare    @publisher_security_mode    int                        
  28814.     declare @publisher_login            sysname
  28815.     declare @publisher_password            nvarchar(524)
  28816.  
  28817.     -- Initialization
  28818.     select @retcode = 0
  28819.     select @detached = 3
  28820.     select @attached = 4
  28821.     select @subscriber_srvid = 0
  28822.     select @subscriber_db = db_name()
  28823.  
  28824.     IF EXISTS (SELECT * from sysmergepublications where
  28825.         allow_subscription_copy = 0)
  28826.     BEGIN
  28827.         RAISERROR (21205, 16, -1, @publication)    
  28828.         RETURN (1)
  28829.     END
  28830.  
  28831.     /* Retention check : Make sure that the subscription copy is not too old */
  28832.     declare PC CURSOR LOCAL FAST_FORWARD for select DISTINCT p.name, p.pubid, p.retention from sysmergepublications p, sysmergesubscriptions s 
  28833.         where s.subid=p.pubid and s.pubid=p.pubid for read only
  28834.     open PC
  28835.     fetch PC into @publication, @pubid, @retention 
  28836.     
  28837.     WHILE (@@fetch_status <> -1)
  28838.         BEGIN
  28839.             /* Compute the retention period cutoff dates per publication */
  28840.             select @retention_date = dateadd(day, -@retention, getdate())
  28841.         
  28842.             if @retention is not NULL and @retention > 0
  28843.             begin
  28844.                 if not exists (select coldate from sysmergearticles , MSmerge_genhistory 
  28845.                     where nickname = art_nick 
  28846.                         and coldate > @retention_date 
  28847.                         and sysmergearticles.pubid = @pubid)
  28848.                     begin
  28849.                         RAISERROR (21307, 16, -1, @publication)
  28850.                         return (1)
  28851.                     end                                
  28852.             end
  28853.             fetch PC into @publication, @pubid, @retention
  28854.         END
  28855.  
  28856.     -- Touch up system tables for merge subscriptions
  28857.  
  28858.     -- Open a cursor for all subscriptions 
  28859.     DECLARE hCallsubscriptions CURSOR LOCAL FAST_FORWARD FOR
  28860.         SELECT subid, subscriber_server from sysmergesubscriptions
  28861.     FOR READ ONLY
  28862.     OPEN hCallsubscriptions
  28863.  
  28864.     FETCH hCallsubscriptions INTO @subid, @subscriber_server
  28865.     WHILE (@@fetch_status <> -1)
  28866.     BEGIN
  28867.         /*
  28868.         ** Validate that the subscriber is a valid server and has an entry in sysservers, else add it
  28869.         */
  28870.         select @subscriber_srvid = NULL
  28871.         select @subscriber_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber_server) collate database_default
  28872.         IF @subscriber_srvid IS NULL
  28873.             BEGIN
  28874.                 EXECUTE @retcode = dbo.sp_addserver @subscriber_server
  28875.                 IF @@error <> 0 OR @retcode <> 0
  28876.                     BEGIN
  28877.                         RAISERROR (14010, 16, -1)
  28878.                            RETURN (1)
  28879.                     END
  28880.                 select @subscriber_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber_server) collate database_default
  28881.                 IF @subscriber_srvid IS NULL
  28882.                     BEGIN
  28883.                         RAISERROR (14010, 16, -1)
  28884.                            RETURN (1)
  28885.                     END
  28886.             END
  28887.  
  28888.     
  28889.         FETCH hCallsubscriptions INTO @subid, @subscriber_server
  28890.     END
  28891.  
  28892.     /*
  28893.     ** Touch up srvid of existing rows in sysmergesubscriptions that correspond
  28894.     ** to the subscription that is not attached. Note that this has to be a bulk 
  28895.     ** update since doing it a row at a time will cause the unique_pubsrvdb constaint
  28896.     ** in sysmergesubscriptions to be violated.
  28897.     */
  28898.     update sysmergesubscriptions 
  28899.         set srvid = fn_serverid(subscriber_server)
  28900.             where status <> @detached
  28901.     if @@ERROR <> 0
  28902.         goto Cleanup
  28903.             
  28904.  
  28905.     -- Open a cursor for all subscriptions that have a status of 'detached'
  28906.     DECLARE hCdetachedsubscriptions CURSOR LOCAL FAST_FORWARD FOR
  28907.         SELECT subid from sysmergesubscriptions where status = @detached 
  28908.     FOR READ ONLY
  28909.     OPEN hCdetachedsubscriptions
  28910.  
  28911.     FETCH hCdetachedsubscriptions INTO @detached_subid
  28912.     WHILE (@@fetch_status <> -1)
  28913.     BEGIN
  28914.         /*
  28915.         ** Select the srvid of the local server
  28916.         */
  28917.         select @subscriber_srvid = 0
  28918.  
  28919.         /* Generate a guid for the Subscriber ID */
  28920.         set @subid = newid()
  28921.  
  28922.         /* Look for existing nickname from any other subscription */
  28923.         exec dbo.sp_MSgetreplnick NULL, NULL , NULL,  @subnickname out
  28924.         if @@ERROR <> 0
  28925.             goto Cleanup
  28926.  
  28927.         /* Generate a new replica nickname from the @subid */
  28928.         if (@subnickname is null)
  28929.             begin
  28930.                 EXECUTE dbo.sp_MSgenreplnickname @subid, @subnickname output
  28931.                 if @@ERROR <> 0
  28932.                     goto Cleanup
  28933.             end                        
  28934.  
  28935.         /*
  28936.         ** Touch up existing rows in sysmergesubscriptions & MSmerge_replinfo.
  28937.         ** Set status of attached subsription as "attached"
  28938.         */
  28939.         update sysmergesubscriptions 
  28940.             set subid                 = @subid, 
  28941.                 srvid                 = @subscriber_srvid, 
  28942.                 subscriber_server         = @@servername,
  28943.                 db_name             = @subscriber_db, 
  28944.                 status                 = @attached,
  28945.                 login_name             = suser_sname(suser_sid())
  28946.             where subid = @detached_subid
  28947.         if @@ERROR <> 0
  28948.             goto Cleanup
  28949.             
  28950.         update MSmerge_replinfo set repid = @subid, 
  28951.             replnickname = @subnickname 
  28952.                 where repid = @detached_subid
  28953.         if @@ERROR <> 0
  28954.             goto Cleanup
  28955.     
  28956.         FETCH hCdetachedsubscriptions INTO @detached_subid 
  28957.     END
  28958.  
  28959.     /* Add pull subscription agents only if MSsubscription_properties exists */
  28960.     if exists (select * from sysobjects where name = 'MSsubscription_properties')
  28961.         begin            
  28962.             -- Add the agents for pull or anonymous subscriptions.
  28963.             DECLARE hCmergesubscription CURSOR LOCAL FAST_FORWARD FOR
  28964.                 SELECT publisher, publisher_db, publication, distributor, enabled_for_syncmgr,
  28965.                     distributor_security_mode, distributor_login, distributor_password,
  28966.                     publisher_security_mode, publisher_login, publisher_password
  28967.                     FROM MSsubscription_properties
  28968.                     -- only do this for merge subscriptions 
  28969.                     where publication_type = 2
  28970.                     --where publication is not NULL and
  28971.                     --    publication <> N'' and
  28972.                     --    subscription_type <> @push
  28973.             FOR READ ONLY
  28974.             OPEN hCmergesubscription
  28975.  
  28976.             FETCH hCmergesubscription INTO @publisher, 
  28977.                 @publisher_db, @publication, @distributor, @enabled_for_syncmgr_int,
  28978.                 @distributor_security_mode, @distributor_login, @distributor_password,
  28979.                 @publisher_security_mode, @publisher_login, @publisher_password
  28980.  
  28981.             WHILE (@@fetch_status <> -1)
  28982.             BEGIN
  28983.                 /* Enable the subscription to be synchronized via SyncMgr if the original one was */
  28984.                 if @enabled_for_syncmgr_int = 0
  28985.                     set @enabled_for_syncmgr = 'false'
  28986.                 else
  28987.                     set @enabled_for_syncmgr = 'true'
  28988.  
  28989.                 if @distributor_security_mode = 0 and @distributor_login is NULL
  28990.                     select @distributor_login = 'sa'
  28991.  
  28992.                 if @publisher_security_mode = 0 and @publisher_login is NULL
  28993.                     select @publisher_login = 'sa'
  28994.  
  28995.  
  28996.                 EXEC @retcode = master.dbo.xp_repl_help_connect @distributor_password OUTPUT
  28997.                 IF @@error <> 0 OR @retcode <> 0
  28998.                 begin
  28999.                     select @retcode = 1
  29000.                     goto Cleanup
  29001.                 end
  29002.  
  29003.                 EXEC @retcode = master.dbo.xp_repl_help_connect @publisher_password OUTPUT
  29004.                 IF @@error <> 0 OR @retcode <> 0
  29005.                 begin
  29006.                     select @retcode = 1
  29007.                     goto Cleanup
  29008.                 end
  29009.  
  29010.                 EXECUTE @retcode  = dbo.sp_addmergepullsubscription_agent 
  29011.                     @publisher = @publisher, 
  29012.                     @publisher_db = @publisher_db, 
  29013.                     @publication = @publication,
  29014.                     @distributor = @distributor,
  29015.                     @subscriber_security_mode = @subscriber_security_mode,    
  29016.                     @subscriber_login = @subscriber_login,
  29017.                     @subscriber_password = @subscriber_password,
  29018.                     @publisher_security_mode = @publisher_security_mode,    
  29019.                     @publisher_login = @publisher_login,
  29020.                     @publisher_password = @publisher_password,
  29021.                     @publisher_encrypted_password = 0,
  29022.                     @distributor_security_mode = @distributor_security_mode,    
  29023.                     @distributor_login = @distributor_login,
  29024.                     @distributor_password = @distributor_password,
  29025.                     @encrypted_password = 0,
  29026.                     @frequency_type  = 2 ,  /* 2== OnDemand */
  29027.                     @enabled_for_syncmgr = @enabled_for_syncmgr,    
  29028.                     @reserved = 'attach_subscription'
  29029.  
  29030.                 if @@error <> 0 or @retcode <> 0 
  29031.                 begin
  29032.                     select @retcode = 1
  29033.                     goto Cleanup
  29034.                 end
  29035.  
  29036.                 FETCH hCmergesubscription INTO @publisher, 
  29037.                     @publisher_db, @publication, @distributor, @enabled_for_syncmgr_int,
  29038.                     @distributor_security_mode, @distributor_login, @distributor_password,
  29039.                     @publisher_security_mode, @publisher_login, @publisher_password
  29040.             END
  29041.         end            
  29042.     else
  29043.         begin
  29044.             /* 
  29045.             ** Check to see if MSsubscription_properties table exists.
  29046.             ** If not, create it.
  29047.             */
  29048.             exec @retcode = dbo.sp_MScreate_sub_tables
  29049.                 @tran_sub_table = 0,
  29050.                 @property_table = 1,
  29051.                 @sqlqueue_table = 0
  29052.             if @@error <> 0 or @retcode <> 0 
  29053.             begin
  29054.                 select @retcode = 1
  29055.                 goto Cleanup
  29056.             end
  29057.         end
  29058.     return 0
  29059. Cleanup:
  29060.     return    1
  29061.     
  29062. go
  29063. EXEC dbo.sp_MS_marksystemobject sp_MSrestore_sub_merge
  29064. GO
  29065.  
  29066.  
  29067.  
  29068. print ''
  29069. print 'Creating procedure sp_MSrestore_sub_tran'
  29070. go
  29071. CREATE PROCEDURE sp_MSrestore_sub_tran (
  29072.     @subscriber_security_mode        int,                        
  29073.     @subscriber_login                sysname,
  29074.     @subscriber_password            nvarchar(524)
  29075.     )
  29076. AS
  29077.  
  29078.     SET NOCOUNT ON
  29079.  
  29080.     /*
  29081.     ** Declarations.
  29082.     */
  29083.     declare @push int
  29084.     declare @retcode int
  29085.     DECLARE @publisher sysname          /* Expression used in the cursor */
  29086.     DECLARE @publisher_db sysname     /* Expression used in the cursor */
  29087.     DECLARE @publication sysname      /* Expression used in the cursor */
  29088.  
  29089.     -- Initialization
  29090.     select @push = 0
  29091.     select @retcode = 0
  29092.  
  29093.  
  29094.     -- Reset agent_id and anonymous agent id and time
  29095.     update MSreplication_subscriptions set agent_id = NULL, subid = NULL,
  29096.         distribution_agent = NULL, time = getdate()
  29097.     if @@error <> 0
  29098.     begin
  29099.         select @retcode = 1
  29100.         goto Cleanup
  29101.     end
  29102.  
  29103.     -- Set attach_state value
  29104.     -- It is only used by pull subscription.
  29105.     -- The attach state is "attached but not processed".
  29106.     update MSsubscription_agents set attach_state = 1
  29107.  
  29108.     -- Add the agents for pull or anonymous subscriptions. 
  29109.     DECLARE hCsubscription CURSOR LOCAL FAST_FORWARD FOR
  29110.         SELECT publisher, publisher_db, publication    
  29111.             FROM MSreplication_subscriptions where 
  29112.                 publication is not NULL and
  29113.                 publication <> N'' and
  29114.                 subscription_type <> @push
  29115.     FOR READ ONLY
  29116.     OPEN hCsubscription
  29117.  
  29118.     FETCH hCsubscription INTO @publisher, 
  29119.         @publisher_db, @publication
  29120.     WHILE (@@fetch_status <> -1)
  29121.     BEGIN
  29122.         EXECUTE @retcode  = dbo.sp_addpullsubscription_agent 
  29123.             @publisher = @publisher, 
  29124.             @publisher_db = @publisher_db, 
  29125.             @publication = @publication, 
  29126.             @subscriber_security_mode = @subscriber_security_mode,    
  29127.             @subscriber_login = @subscriber_login,
  29128.             @subscriber_password = @subscriber_password,
  29129.             @frequency_type  = 2 ,  /* 2== OnDemand */
  29130.             @reserved = 'no_change_to_properties'
  29131.  
  29132.         if @@error <> 0 or @retcode <> 0 
  29133.         begin
  29134.             select @retcode = 1
  29135.             goto Cleanup
  29136.         end
  29137.  
  29138.         FETCH hCsubscription INTO @publisher, 
  29139.             @publisher_db, @publication
  29140.     END
  29141.  
  29142. Cleanup:
  29143.     -- Nothing to cleanup
  29144.     return    @retcode
  29145. go
  29146. EXEC dbo.sp_MS_marksystemobject sp_MSrestore_sub_tran
  29147. GO
  29148.  
  29149. print ''
  29150. print 'Creating procedure sp_MSrestore_sub'
  29151. go
  29152. CREATE PROCEDURE sp_MSrestore_sub (
  29153.     @subscriber_security_mode        int,                        
  29154.     @subscriber_login                sysname,
  29155.     @subscriber_password            nvarchar(524)
  29156.     )
  29157. AS
  29158.  
  29159.     SET NOCOUNT ON
  29160.  
  29161.     /*
  29162.     ** Declarations.
  29163.     */
  29164.     declare @retcode int
  29165.  
  29166.     -- Initialization
  29167.     select @retcode = 0
  29168.  
  29169.     if exists (select * from sysobjects where name = 'MSreplication_subscriptions')
  29170.     begin
  29171.         exec @retcode = dbo.sp_MSrestore_sub_tran
  29172.             @subscriber_security_mode = @subscriber_security_mode,    
  29173.             @subscriber_login = @subscriber_login,
  29174.             @subscriber_password = @subscriber_password
  29175.  
  29176.         if @@error <> 0 or @retcode <> 0
  29177.         begin
  29178.             select @retcode = 1
  29179.             goto Cleanup
  29180.         end
  29181.     end
  29182.     if exists (select * from sysobjects where name = 'sysmergesubscriptions')
  29183.     begin
  29184.         exec @retcode = dbo.sp_MSrestore_sub_merge
  29185.             @subscriber_security_mode = @subscriber_security_mode,    
  29186.             @subscriber_login = @subscriber_login,
  29187.             @subscriber_password = @subscriber_password
  29188.         if @@error <> 0 or @retcode <> 0
  29189.         begin
  29190.             select @retcode = 1
  29191.             goto Cleanup
  29192.         end
  29193.     end
  29194.  
  29195. Cleanup:
  29196.     if exists (select * from sysobjects where name = 'MSreplication_restore_stage')
  29197.         drop table MSreplication_restore_stage
  29198.  
  29199.     return    @retcode
  29200. go
  29201. EXEC dbo.sp_MS_marksystemobject sp_MSrestore_sub
  29202. GO
  29203.  
  29204.  
  29205. raiserror('Creating procedure sp_validatemergepullsubscription', 0,1)
  29206. GO
  29207.  
  29208. CREATE PROCEDURE sp_validatemergepullsubscription
  29209.     (@publication            sysname,
  29210.      @publisher                sysname,
  29211.      @publisher_db            sysname,
  29212.      @level                    tinyint
  29213.      ) AS
  29214.  
  29215.     declare @subscriber_srvid        int
  29216.     declare @retcode                int
  29217.     declare @pubid                    uniqueidentifier
  29218.     declare @subscriber                sysname
  29219.     declare @subscriber_db            sysname
  29220.     /*
  29221.     ** Security Check
  29222.     */
  29223.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  29224.     IF @@ERROR <> 0 or @retcode <> 0
  29225.         return (1)
  29226.  
  29227.     select @subscriber = @@SERVERNAME, @subscriber_db=db_name()
  29228.     select @subscriber_srvid = srvid from master..sysservers where LOWER(srvname)=LOWER(@subscriber) collate database_default
  29229.  
  29230.     select @pubid=pubid from sysmergepublications where LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db and name=@publication
  29231.     if @pubid is NULL
  29232.         begin
  29233.             raiserror (20026, 16, -1, @publication)
  29234.             return (1)
  29235.         end
  29236.     if @level <0 or @level > 3
  29237.         begin
  29238.             raiserror(21184, 16, -1, '@level', '1', '2','3')
  29239.             return (1)
  29240.         end
  29241.  
  29242.     if not exists (select * from sysmergesubscriptions where pubid=@pubid and db_name=@subscriber_db and srvid=@subscriber_srvid)
  29243.         begin
  29244.             raiserror(14055, 16, -1)
  29245.             return (1)
  29246.         end
  29247.  
  29248.     update sysmergesubscriptions set validation_level=@level where pubid=@pubid and db_name=@subscriber_db and srvid=@subscriber_srvid
  29249.     if @@ERROR<>0
  29250.         return (1)
  29251.     return (0)
  29252.  
  29253. go
  29254. exec dbo.sp_MS_marksystemobject sp_validatemergepullsubscription
  29255. go
  29256. grant exec on dbo.sp_validatemergepullsubscription to public
  29257. go
  29258.  
  29259.  
  29260. print ''
  29261. print 'Creating procedure sp_MSprepare_sub_for_detach'
  29262. go
  29263. CREATE PROCEDURE sp_MSprepare_sub_for_detach 
  29264.     @subscriber_srvid     int,
  29265.     @subscriber_db          sysname
  29266. as
  29267.     set nocount on
  29268.     declare @detached     int
  29269.     select @detached = 3
  29270.     
  29271.     -- Stage: attach and restore subscription.
  29272.     update dbo.MSreplication_restore_stage set stage_id = 2
  29273.     if @@error <> 0
  29274.         return 1
  29275.  
  29276.     /* Touch up the merge subscriptions for detach */
  29277.     if exists (select * from sysobjects where name = 'sysmergesubscriptions')
  29278.     begin            
  29279.         /* Mark all subscriptions to have a status of detached */
  29280.         update sysmergesubscriptions set status = @detached where srvid = @subscriber_srvid and db_name = @subscriber_db
  29281.         if @@error <> 0
  29282.             return 1
  29283.     end        
  29284.     if exists (select * from sysobjects where name = 'MSsub_identity_range')
  29285.     begin
  29286.         -- Set range to 0 so that the attached db will get new ranges
  29287.         -- Refer to sp_MSsub_check_identity
  29288.         update MSsub_identity_range set range = 0
  29289.         if @@error <> 0
  29290.             return 1
  29291.     end    
  29292. go
  29293. EXEC dbo.sp_MS_marksystemobject sp_MSprepare_sub_for_detach
  29294. GO
  29295.  
  29296. print ''
  29297. print 'Creating procedure sp_MSsub_check_identity'
  29298. go
  29299. CREATE PROCEDURE sp_MSsub_check_identity
  29300. @lower_bound_id int
  29301. as
  29302.     declare @retcode int
  29303.     declare @cmd nvarchar(1000)
  29304.     declare @objid int, @threshhold bigint, @range bigint, @next_seed bigint
  29305.     declare    @last_seed bigint, @identity_so_far bigint, @threshold int
  29306.     declare @table_name sysname
  29307.     declare @qualname nvarchar(512)
  29308.  
  29309.     --  Security Check
  29310.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  29311.     IF @@ERROR <> 0 or @retcode <> 0
  29312.     RETURN(1)
  29313.  
  29314.     -- This proc will be called by distribution agent called repeatedly until
  29315.     -- one result returned
  29316.     if exists (select * from sysobjects where name = 'MSsub_identity_range')
  29317.     begin
  29318.         while 1 = 1
  29319.         begin
  29320.             select @objid = null
  29321.             select top 1 @objid = objid from MSsub_identity_range where
  29322.                 objid > @lower_bound_id 
  29323.                 order by objid ASC
  29324.             if @objid is null
  29325.                 break
  29326.  
  29327.             select @lower_bound_id = @objid
  29328.             -- Since we don't always clean up the subscriber, Skipping invalid entry.
  29329.             if object_name(@objid) is null 
  29330.                 continue
  29331.             if objectproperty(@objid, 'TableHasIdentity') <> 1
  29332.                 continue
  29333.  
  29334.             exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  29335.  
  29336.             select @range = range, @last_seed = last_seed, @threshold = threshold from 
  29337.                 MSsub_identity_range where objid=@objid
  29338.                 
  29339.             if @range = 0
  29340.                 -- First time after initial bcp, always request a new range
  29341.                 -- return this object
  29342.                 break
  29343.             else
  29344.             begin                 
  29345.  
  29346.                 -- Leave one slot unused. This is to prevent violation of primary key constraint
  29347.                 -- if the next value is used by a subscriber and the publisher has received it.
  29348.                 -- It seems the pk constraint will be validated before this check.
  29349.                 declare @actual_range int
  29350.                 if @range > 0
  29351.                     select @actual_range = @range - 1
  29352.                 else
  29353.                     select @actual_range = @range + 1
  29354.  
  29355.                 select @identity_so_far = ident_current(@qualname)
  29356.  
  29357.                 if 100*(@identity_so_far - @last_seed)/@actual_range >= @threshold
  29358.                     -- Need new range
  29359.                     break
  29360.             end
  29361.  
  29362.             select @lower_bound_id = @objid
  29363.         end
  29364.     end
  29365.     select @table_name = object_name(@objid)            
  29366.  
  29367.     -- Return nothing if @table_name is null, which means no more table needs to be adjust
  29368.     select 'objid' = @objid, 'table_name' = @table_name where @objid is not null    
  29369. go
  29370. EXEC dbo.sp_MS_marksystemobject sp_MSsub_check_identity
  29371. GO
  29372.  
  29373. print ''
  29374. print 'Creating procedure sp_MSsub_cleanup_orphans'
  29375. go
  29376. CREATE PROCEDURE sp_MSsub_cleanup_orphans AS
  29377.  
  29378.  
  29379.     /*
  29380.     ** Security Check
  29381.     */
  29382.     -- Internal sp, not granted to public.
  29383.     -- Ignore all errrors
  29384.  
  29385.        if exists (select * from sysobjects where name = 'MSreplication_objects')
  29386.     begin
  29387.         delete MSreplication_objects where not exists (select * from sysobjects
  29388.             where name = object_name)
  29389.         if not exists (select * from MSreplication_objects)
  29390.             drop table MSreplication_objects
  29391.     end
  29392.             
  29393.        if exists (select * from sysobjects where name = 'MSsub_identity_range')
  29394.     begin
  29395.         delete MSsub_identity_range where not exists (select * from sysobjects
  29396.             where id = objid)
  29397.         if not exists (select * from MSsub_identity_range)
  29398.             drop table MSsub_identity_range
  29399.     end
  29400. GO
  29401. EXEC dbo.sp_MS_marksystemobject sp_MSsub_cleanup_orphans
  29402. GO
  29403.  
  29404. print ''
  29405. print 'Creating procedure sp_MSsub_cleanup_prop_table'
  29406. go
  29407. CREATE PROCEDURE sp_MSsub_cleanup_prop_table AS
  29408.  
  29409.  
  29410.     /*
  29411.     ** Security Check
  29412.     */
  29413.     -- Internal sp, not granted to public.
  29414.     -- Ignore all errrors
  29415.     declare @drop_table bit
  29416.  
  29417.     -- Init to drop table
  29418.     select @drop_table = 1
  29419.  
  29420.        if exists (select * from sysobjects where name = 'MSreplication_subscriptions')
  29421.     begin
  29422.         if exists (select * from MSreplication_subscriptions where 
  29423.             subscription_type <> 0)
  29424.             select @drop_table = 0
  29425.     end
  29426.             
  29427.        if exists (select * from sysobjects where name = 'sysmergesubscriptions')
  29428.     begin
  29429.         if exists (select * from sysmergesubscriptions where subid <> pubid and 
  29430.             db_name = db_name() and 
  29431.             subscriber_server = convert(sysname, SERVERPROPERTY('ServerName')) collate database_default and
  29432.             subscription_type <> 0)
  29433.             select @drop_table = 0
  29434.     end
  29435.  
  29436.     if @drop_table = 1
  29437.         drop table dbo.MSsubscription_properties
  29438.  GO
  29439. EXEC dbo.sp_MS_marksystemobject sp_MSsub_cleanup_prop_table
  29440. GO
  29441.  
  29442. print ''
  29443. print 'Creating procedure sp_MSreseed'
  29444. go
  29445.  
  29446. CREATE PROCEDURE sp_MSreseed(
  29447. @objid                int,
  29448. @next_seed            bigint,
  29449. @range                 bigint,
  29450. @is_publisher        int = 0,
  29451. @check_only         bit = 0,
  29452. @drop_only            bit = 0,
  29453. @initial_setting     bit = 0,
  29454. @bound_value        bigint = 0
  29455. )
  29456. AS
  29457. declare @min_value                bigint
  29458. declare @max_value                bigint
  29459. declare @constraintname            sysname
  29460. declare @artid                    uniqueidentifier
  29461. declare @min_str                nvarchar(20)
  29462. declare @identity_column        sysname
  29463. declare @colid                    int
  29464. declare @colname                sysname
  29465. declare @max_str                nvarchar(20)
  29466. declare @owner                    sysname
  29467. declare @tablename                sysname
  29468. declare @qualname                nvarchar(270)
  29469. declare @dbname                    sysname
  29470. declare @prefix                    sysname
  29471.  
  29472. SET NOCOUNT ON
  29473.     select @prefix = 'repl_identity_range_'
  29474.     select @colid=1
  29475.     select @dbname=db_name()
  29476.     select @colname=name from syscolumns where colid=@colid and id = @objid
  29477.     while COLUMNPROPERTY(@objid, @colname, 'IsIdentity')=0 and @colname is not NULL
  29478.     begin
  29479.         select @colid = @colid + 1
  29480.         select @colname=name from syscolumns where colid=@colid and id = @objid
  29481.     end
  29482.     if @colname is NULL
  29483.     begin
  29484.         raiserror('there is no identity column in this table', 16, -1)
  29485.         return (1)
  29486.     end
  29487.     if @range > 0
  29488.     begin 
  29489.         select @min_value = @next_seed 
  29490.         if @initial_setting = 1
  29491.                     select @min_value = @bound_value - 1 -- allow for race condition with ident_current.             
  29492.         -- @next_seed + @range can be used by this db, but not other db.
  29493.         -- Leave one slot unused. This is to prevent violation of primary key constraint
  29494.         -- if the next value is used by a subscriber and the publisher has received it.
  29495.         -- It seems the pk constraint will be validated before this check.
  29496.         -- select @max_value = @next_seed + @range + 1
  29497.         select @max_value = @next_seed + @range
  29498.         select @next_seed=@next_seed + 1
  29499.     end
  29500.     else
  29501.     begin
  29502.         select @max_value = @next_seed 
  29503.         if @initial_setting = 1
  29504.                     select @max_value = @bound_value + 1 -- allow for race condition with ident_current.                     
  29505.         -- @next_seed + @range can be used by this db, but not other db.
  29506.         -- Leave one slot unused. This is to prevent violation of primary key constraint
  29507.         -- if the next value is used by a subscriber and the publisher has received it.
  29508.         -- It seems the pk constraint will be validated before this check.
  29509.         -- select @min_value = @next_seed + @range - 1
  29510.         select @min_value = @next_seed + @range
  29511.         select @next_seed=@next_seed - 1
  29512.     end
  29513.  
  29514.     select @min_str = convert(nvarchar, @min_value)
  29515.     select @max_str = convert(nvarchar, @max_value)
  29516.     select @owner = user_name(uid) from sysobjects where id = @objid
  29517.     select @tablename = object_name(@objid)
  29518.     select @qualname = QUOTENAME(@owner) + '.' + QUOTENAME(@tablename)
  29519.  
  29520.     if @check_only = 0
  29521.     begin 
  29522.         DBCC CHECKIDENT(@qualname, RESEED, @next_seed) with no_infomsgs
  29523.         if @@ERROR<>0
  29524.                 return (1)
  29525.     end
  29526.  
  29527.     if @is_publisher < 0
  29528.     begin
  29529.         -- Used by tran
  29530.         -- Publisher side constraint maybe transfered to subscriber.
  29531.         -- If so, it will be dropped with code below.
  29532.         select @constraintname = NULL
  29533.           select @constraintname = name from sysobjects where name like @prefix + 'tran_[0-9]%' and 
  29534.             xtype='C' and
  29535.             parent_obj = @objid
  29536.         if @constraintname is not null
  29537.         begin
  29538.             exec ('alter table '+ @qualname + ' drop constraint ' + @constraintname)
  29539.             if @@ERROR<>0
  29540.                 return (1)
  29541.         end
  29542.           select @constraintname = @prefix + 'tran_' + convert(nvarchar(10), @objid)
  29543.     end
  29544.     else
  29545.     begin 
  29546.         -- Used by merge
  29547.         select @artid=artid from dbo.sysmergearticles where objid=@objid
  29548.         select @constraintname = @prefix + 'pub_' + convert(nvarchar(36), @artid)
  29549.         select @constraintname = REPLACE(@constraintname, '-', '_')
  29550.         if exists (select * from sysobjects where name = @constraintname and xtype='C')
  29551.         begin
  29552.             exec ('alter table '+ @qualname + ' drop constraint ' + @constraintname)
  29553.             if @@ERROR<>0
  29554.                 return (1)
  29555.         end
  29556.         select @constraintname = @prefix + 'repub_' + convert(nvarchar(36), @artid)
  29557.         select @constraintname = REPLACE(@constraintname, '-', '_')
  29558.         if exists (select * from sysobjects where name = @constraintname and xtype='C')
  29559.         begin
  29560.             exec ('alter table '+ @qualname + ' drop constraint ' + @constraintname)
  29561.             if @@ERROR<>0
  29562.                 return (1)
  29563.         end
  29564.         select @constraintname = @prefix + 'sub_' + convert(nvarchar(36), @artid)
  29565.         select @constraintname = REPLACE(@constraintname, '-', '_')
  29566.         if exists (select * from sysobjects where name = @constraintname and xtype='C')
  29567.         begin
  29568.             exec ('alter table '+ @qualname + ' drop constraint ' + @constraintname)
  29569.             if @@ERROR<>0
  29570.                 return (1)
  29571.         end    
  29572.         if @is_publisher=1
  29573.             select @constraintname = @prefix + 'pub_' + convert(nvarchar(36), @artid)
  29574.         else 
  29575.             if @is_publisher = 2
  29576.                 select @constraintname = @prefix + 'repub_' + convert(nvarchar(36), @artid)
  29577.             else
  29578.                 select @constraintname = @prefix + 'sub_' + convert(nvarchar(36), @artid)
  29579.         select @constraintname = REPLACE(@constraintname, '-', '_')
  29580.     end
  29581.  
  29582.     -- Don't add new constraint if only drop is needed.
  29583.     if @drop_only = 1
  29584.         return (0)
  29585.  
  29586.     declare @qualcolname sysname
  29587.     select @qualcolname = quotename(@colname)
  29588.  
  29589.     exec ('alter table '+ @qualname + ' with NOCHECK add CONSTRAINT ' + @constraintname + ' check NOT FOR REPLICATION ( ' + @qualcolname + ' > ' 
  29590.         + @min_str + ' and ' + @qualcolname + ' < ' + @max_str + ')')
  29591.     if @@ERROR<>0
  29592.         return (1)
  29593.     return (0)
  29594. GO
  29595. EXEC dbo.sp_MS_marksystemobject sp_MSreseed
  29596. GO
  29597.  
  29598. print ''
  29599. print 'Creating procedure sp_MSsub_set_identity'
  29600. go
  29601. CREATE PROCEDURE sp_MSsub_set_identity
  29602. @objid int,
  29603. @threshold int,
  29604. @range bigint,
  29605. @next_seed bigint
  29606. as
  29607.     declare @retcode int
  29608.  
  29609.     --  Security Check
  29610.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  29611.     IF @@ERROR <> 0 or @retcode <> 0
  29612.     RETURN(1)
  29613.  
  29614.     -- Stored last_seed in @next_seed
  29615.     select @next_seed = @next_seed - @range
  29616.  
  29617.     update MSsub_identity_range set 
  29618.         last_seed = @next_seed,
  29619.         threshold = @threshold,
  29620.         range = @range
  29621.         where objid = @objid
  29622.     IF @@ERROR <> 0
  29623.         return 1
  29624.     -- RESEED and change constraint
  29625.     exec @retcode = dbo.sp_MSreseed
  29626.         @objid = @objid,
  29627.         @next_seed = @next_seed,
  29628.         @range = @range,
  29629.         @is_publisher = -1
  29630.     IF @@ERROR <> 0 OR @retcode <> 0
  29631.         return 1
  29632. go
  29633. EXEC dbo.sp_MS_marksystemobject sp_MSsub_set_identity
  29634. GO
  29635.  
  29636. print ''
  29637. print 'Creating procedure sp_MSinstance_qv'
  29638. go
  29639. create procedure sp_MSinstance_qv @qv varchar(10)
  29640. as
  29641. begin
  29642.     declare @qv_value varchar(10)
  29643.     set nocount on
  29644.     -- -------------------------------------------------------------
  29645.     --
  29646.     -- BUGBUG 236535 : IA64 workaround
  29647.     --
  29648.     -- since xp_qv has not been ported yet - detect the
  29649.     -- the platform and preset the config for IA64 servers
  29650.     --
  29651.     -- NOTE : this code should be later cleaned up
  29652.     -- once SETUP is completely functional on IA64
  29653.     --
  29654.     -- -------------------------------------------------------------
  29655.     declare @fia64 bit
  29656.     
  29657.     create table #tosversion ( propid int, propname sysname collate database_default, value int null, charvalue nvarchar(255) collate database_default)
  29658.     insert into #tosversion (propid, propname, value, charvalue)
  29659.         exec master.dbo.xp_msver N'Platform'
  29660.     
  29661.     select @fia64 = case when patindex(N'%IA64%', charvalue) != 0 then 1 else 0 end
  29662.     from #tosversion
  29663.  
  29664.     if (@fia64 = 1)
  29665.     begin
  29666.         select @qv_value = 0
  29667.     end
  29668.     else
  29669.     begin
  29670.         if serverproperty('instancename') is null
  29671.             exec @qv_value = master.dbo.xp_qv @qv    
  29672.         else
  29673.         begin
  29674.             declare @instance_name varchar(257)
  29675.             select @instance_name = cast(serverproperty('instancename') as varchar(257))
  29676.             exec @qv_value = master.dbo.xp_qv @qv, @instance_name
  29677.         end
  29678.     end
  29679.     -- -------------------------------------------------------------
  29680.     return @qv_value
  29681. end
  29682. go
  29683. EXEC dbo.sp_MS_marksystemobject sp_MSinstance_qv
  29684. GO
  29685.  
  29686. print ''
  29687. print 'Creating procedure sp_MSget_shared_agent'
  29688. go
  29689. CREATE PROCEDURE sp_MSget_shared_agent (
  29690.     @server_name sysname,
  29691.     @database_name sysname,
  29692.     @agent_type int,
  29693.     @publisher sysname = NULL -- Only usec by third party.
  29694.     ,@publisher_db sysname = NULL -- Only usec by third party.
  29695.     ) AS
  29696.  
  29697.     declare @server_id smallint
  29698.     select @server_id = srvid from master..sysservers where
  29699.         UPPER(srvname) = UPPER(@server_name) collate database_default
  29700.     -- push agents to SQL publications
  29701.     if @agent_type = 0
  29702.     begin
  29703.         if object_id('syssubscriptions') is not null
  29704.         begin
  29705.             select top 1 N'job_id' = distribution_jobid from syssubscriptions s, sysarticles a,
  29706.                 syspublications p where
  29707.                 srvid = @server_id and
  29708.                 dest_db = @database_name and
  29709.                 subscription_type = 0 and
  29710.                 independent_agent = 0 and
  29711.                 s.artid = a.artid and
  29712.                 p.pubid = a.pubid
  29713.         end
  29714.     end
  29715.     -- push agents to third party
  29716.     else if @agent_type = 1
  29717.     begin
  29718.         if object_id('MSsubscriptions') is not null
  29719.         begin
  29720.             declare @publisher_id smallint
  29721.             select top 1 @publisher_id from master..sysservers where
  29722.                 UPPER(srvname) = UPPER(@publisher) collate database_default
  29723.             select top 1 N'job_id' = job_id from MSdistribution_agents where
  29724.                 subscriber_id = @server_id and
  29725.                 subscriber_db = @database_name and
  29726.                 publication = N'ALL' and
  29727.                 publisher_id = @publisher_id and
  29728.                 publisher_db = @publisher_db and
  29729.                 subscription_type = 0
  29730.         end
  29731.     end
  29732.     else if @agent_type = 2
  29733.     begin
  29734.         if object_id('MSreplication_subscriptions') is not null
  29735.         begin
  29736.             -- For subscriptions added through Active X control
  29737.             -- where there's no local agent created, we still don't
  29738.             -- want to create new agent.
  29739.             select top 1 N'job_id' = agent_id from MSreplication_subscriptions where
  29740.                 UPPER(publisher) = UPPER(@server_name) and
  29741.                 publisher_db = @database_name and
  29742.                 independent_agent = 0 and
  29743.                 subscription_type in (1,2)
  29744.         end
  29745.     end
  29746. GO
  29747. EXEC dbo.sp_MS_marksystemobject sp_MSget_shared_agent
  29748. GO
  29749.  
  29750. print ''
  29751. print 'Creating procedure sp_MSrepl_backup_start'
  29752. go
  29753. create procedure sp_MSrepl_backup_start
  29754. as
  29755.     declare @sync_bit int
  29756.     declare @dist_bit int
  29757.  
  29758.     set nocount on
  29759.     
  29760.     set @sync_bit = 32
  29761.     set @dist_bit = 16
  29762.  
  29763.     -- If this is a distribution database and it is marked by 'sync with backup'
  29764.     if exists (select * from master.dbo.sysdatabases where
  29765.         name = db_name() collate database_default and
  29766.         category & (@sync_bit | @dist_bit) = @sync_bit | @dist_bit)
  29767.     begin
  29768.         update MSrepl_backup_lsns set next_xact_id = t2.xact_id, next_xact_seqno = m.xact_seqno from 
  29769.             (select tm.publisher_database_id, max(tm.xact_seqno) from 
  29770.                 -- max seqno of xacts not involved in partial tran processing
  29771.                 (select t.publisher_database_id, max(substring(t.xact_seqno, 1, 10)) from 
  29772.                     MSrepl_transactions t where
  29773.                     not t.xact_id = 0x0 
  29774.                     group by t.publisher_database_id, substring(t.xact_seqno, 1, 10)
  29775.                     having count(t.xact_seqno) < 2
  29776.                 union
  29777.                 -- max seqno of xacts involved in and completed partial tran processing
  29778.                 select t.publisher_database_id, max(substring(xact_seqno, 1, 10)) from
  29779.                     MSrepl_transactions t where
  29780.                     not t.xact_id = 0x0 
  29781.                     and t.xact_id = substring(t.xact_seqno, 1, 10)
  29782.                     group by t.publisher_database_id
  29783.                 )as tm(publisher_database_id, xact_seqno) -- derived table containing up to 2 rows per publication_database_id
  29784.             group by tm.publisher_database_id -- derived table containing up to 1 row per publication_database_id
  29785.             )as m(publisher_database_id, xact_seqno), 
  29786.             MSrepl_transactions t2                
  29787.         where m.publisher_database_id = MSrepl_backup_lsns.publisher_database_id and
  29788.                 t2.publisher_database_id = MSrepl_backup_lsns.publisher_database_id and
  29789.                 t2.xact_seqno    = m.xact_seqno
  29790.         if @@error <> 0
  29791.             return 1
  29792.     end
  29793.  
  29794.     return 0
  29795. go
  29796. EXEC dbo.sp_MS_marksystemobject sp_MSrepl_backup_start
  29797. GO
  29798.  
  29799. print ''
  29800. print 'Creating procedure sp_MSrepl_backup_complete'
  29801. go
  29802. create procedure sp_MSrepl_backup_complete
  29803. as
  29804.     declare @sync_bit int
  29805.     declare @dist_bit int
  29806.  
  29807.     set nocount on
  29808.     
  29809.     set @sync_bit = 32
  29810.     set @dist_bit = 16
  29811.  
  29812.     -- If this is a distribution database and it is marked by 'sync with backup'
  29813.     if exists (select * from master.dbo.sysdatabases where
  29814.         name = db_name() collate database_default and
  29815.         category & (@sync_bit | @dist_bit) = @sync_bit | @dist_bit)
  29816.     begin
  29817.         update MSrepl_backup_lsns set valid_xact_id = next_xact_id, 
  29818.             valid_xact_seqno = next_xact_seqno 
  29819.         if @@error <> 0
  29820.             return 1
  29821.     end
  29822.     return 0
  29823. go
  29824. EXEC dbo.sp_MS_marksystemobject sp_MSrepl_backup_complete
  29825. GO
  29826.  
  29827. --
  29828. -- sp_MSadd_compensating_cmd
  29829. --
  29830. -- Owner: KaushikC
  29831. --
  29832. -- Proc executed from publisher that POSTS COMPENSATING command into 
  29833. -- Publisher Log OR Inserts COMPENSATING command into Distributor 
  29834. -- command table for a given subscriber/subscriberdb based on the mode
  29835. --
  29836. -- Parameters:
  29837. --    @orig_srv            originating subscriber
  29838. --    @orig_db            subscriber db
  29839. --    @command            command or command fragment (max 4000 chars)
  29840. --    @article_id         article id
  29841. --    @publication_id        publication id
  29842. --    @cmdstate            flag to indicate command fragment - to handle case
  29843. --                        where actual commands len exceeds 4000 chars
  29844. --    @mode                mode of operation, 0 = POST IN PUBLISHER LOG
  29845. --                        1 = INSERT IN DISTRIBUTOR COMMAND TABLE
  29846. --    @setprefix            flag to indicate if we should prefix command with originator info
  29847. --
  29848. -- Security: Public access. Internal security check for publish
  29849. --
  29850. raiserror('Creating procedure sp_MSadd_compensating_cmd', 0,1)
  29851. go
  29852. CREATE PROCEDURE sp_MSadd_compensating_cmd(
  29853.     @orig_srv            sysname,
  29854.     @orig_db            sysname,
  29855.     @command            nvarchar(4000),
  29856.     @article_id         int,
  29857.     @publication_id        int,
  29858.     @cmdstate            bit=0,
  29859.     @mode                int=0,
  29860.     @setprefix            bit=1
  29861. )    
  29862. AS
  29863. BEGIN
  29864.     set nocount on
  29865.     declare     
  29866.  
  29867.     --
  29868.     -- variable declarations for all modes
  29869.     --
  29870.                 @retcode            int,
  29871.                 @command_id         int,                -- command sequence
  29872.                 @partial_cmd         int,                -- partial command flag
  29873.                 @curlen                int,                -- current length to read
  29874.                 @start_index        int,                -- index to start reading
  29875.                 @max_fragment        int,                -- max binary fragment
  29876.                 @full_command        nvarchar(4000),        -- qualified command
  29877.                 @readsize            int,                -- read length chars or bytes based on mode
  29878.                 @mode_postpublog     int,
  29879.                 @mode_insdistcmd     int,
  29880.  
  29881.     --
  29882.     -- variable declarations specific to mode = 1
  29883.     --
  29884.  
  29885.                 @partial_cmdbit        bit,                -- partial command flag
  29886.                 @xact_seqno            varbinary(16),
  29887.                 @publisher_id         int,                -- publisher ID
  29888.                 @publisher_db        sysname,             -- publisher Db
  29889.                 @distributor        sysname,            -- distribution server
  29890.                 @distribdb            sysname,            -- distribution db
  29891.                 @charsize            int,                -- char size
  29892.                 @binary_cmd            varbinary(1024),    -- Binary converted command
  29893.                 @distproc            nvarchar(300)        -- RPC string
  29894.  
  29895.     --
  29896.     -- Security Check
  29897.     --
  29898.     exec @retcode = dbo.sp_MSreplcheck_publish
  29899.     if ((@@ERROR != 0) or (@retcode != 0))
  29900.         return(1)
  29901.  
  29902.     --
  29903.     -- Initialize
  29904.     --
  29905.     select         @mode_postpublog = 0,
  29906.                 @mode_insdistcmd = 1
  29907.  
  29908.     if (@mode NOT in (@mode_postpublog,@mode_insdistcmd))
  29909.         return(1)
  29910.     --
  29911.     -- We will not post final partial empty(may contain space) command 
  29912.     -- since logreader skips empty commands and this causes distribution 
  29913.     -- agent to get confused when it selects the commands to read.
  29914.     -- If this partial command happens to be the final partial command which 
  29915.     -- has a single space - then add a comment
  29916.     --
  29917.     if  ((len(@command) = 0) and (@cmdstate = 0))
  29918.         select @command = N'/*c*/'
  29919.     --
  29920.     -- process based on @mode
  29921.     --
  29922.     if (@mode = @mode_insdistcmd)
  29923.     begin
  29924.         select     @publisher_db = db_name(),
  29925.                 @publisher_id = srvid 
  29926.         from master.dbo.sysservers where UPPER(srvname) = UPPER(@@servername) collate database_default
  29927.  
  29928.         --
  29929.         -- Get distribution server information for remote RPC calls
  29930.         --
  29931.         EXECUTE @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  29932.                                     @distribdb  = @distribdb OUTPUT
  29933.         if ((@@ERROR != 0) or (@retcode != 0))
  29934.             return(1)
  29935.         
  29936.         --
  29937.         -- Get the new xact_seqno
  29938.         --
  29939.         create table #new_xact_seqno ( seqno varbinary(16) NOT NULL )
  29940.         select @distproc = RTRIM(@distributor) + '.' + @distribdb +'.dbo.sp_MSget_new_xact_seqno'
  29941.         insert into #new_xact_seqno
  29942.             EXECUTE @retcode = @distproc
  29943.                 @publisher_id = @publisher_id,
  29944.                 @publisher_db = @publisher_db,
  29945.                 @len = 14
  29946.         if ((@@ERROR != 0) or (@retcode != 0))
  29947.             return(1)
  29948.         select @xact_seqno = seqno from #new_xact_seqno    
  29949.         select @distproc = RTRIM(@distributor) + '.' + @distribdb +'.dbo.sp_MSadd_repl_command'
  29950.     end
  29951.     
  29952.     --
  29953.     -- Do the command insertion in a tran
  29954.     --
  29955.     select @full_command = case when (@setprefix = 1) then 
  29956.                                 QUOTENAME(@orig_srv) + QUOTENAME(@orig_db) + @command
  29957.                                 else @command end
  29958.     begin tran sp_MSadd_compensating_cmd
  29959.     
  29960.     --
  29961.     -- process the command
  29962.     -- for @mode_postpublog : just call sp_replpostcmd and that will do the job
  29963.     -- for @mode_insdistcmd : break the command into 1024 sized commands and add
  29964.     --
  29965.     if (@mode = @mode_postpublog)
  29966.     begin
  29967.         select     @partial_cmd = CASE when (@cmdstate = 1) then 1 else 0 END
  29968.         exec @retcode = dbo.sp_replpostcmd 
  29969.                 @partial_cmd,
  29970.                 @publication_id, 
  29971.                 @article_id, 
  29972.                 12,
  29973.                 @full_command
  29974.         if (@@ERROR != 0 or @retcode != 0)
  29975.             GOTO UNDO
  29976.     end
  29977.     else if (@mode = @mode_insdistcmd)
  29978.     begin
  29979.         select     @command_id = 0,
  29980.                 @start_index = 1,
  29981.                 @max_fragment = 1024,
  29982.                 @charsize = 2,
  29983.                 @curlen = LEN(@full_command),
  29984.                 @readsize = DATALENGTH(@full_command)
  29985.  
  29986.         while (@readsize > 0)
  29987.         begin
  29988.             -- set command id
  29989.             select @command_id = @command_id + 1
  29990.  
  29991.             -- Check if we have to process partial command
  29992.             if (@readsize > @max_fragment)
  29993.             begin
  29994.                 --
  29995.                 -- we have partial command to send
  29996.                 --
  29997.                 select @curlen = @max_fragment / @charsize
  29998.                 select     @partial_cmdbit = 1,
  29999.                         @binary_cmd = CAST(
  30000.                             SUBSTRING(@full_command, @start_index, @curlen)
  30001.                             AS varbinary(1024)),
  30002.                         @readsize = @readsize - @max_fragment
  30003.  
  30004.                 select @start_index = @start_index + @curlen
  30005.                 select @curlen = @readsize / @charsize
  30006.             end
  30007.             else
  30008.             begin
  30009.                 --
  30010.                 -- last fragment to send - end of command
  30011.                 -- check for command state - if state is PARTIAL_CMD (1)
  30012.                 -- then set the partial bit even though this is the last fragment
  30013.                 --
  30014.                 select     @partial_cmdbit = CASE when (@cmdstate = 1) then 1 else 0 END,
  30015.                         @binary_cmd = CAST(
  30016.                             SUBSTRING(@full_command, @start_index, @curlen) 
  30017.                             AS varbinary(1024)),
  30018.                         @readsize = 0
  30019.             end
  30020.                 
  30021.             --
  30022.             -- Add the command to the distributor
  30023.             --
  30024.             EXECUTE @retcode = @distproc
  30025.                 @publisher_id = @publisher_id, 
  30026.                 @publisher_db = @publisher_db, 
  30027.                 @xact_seqno = @xact_seqno,
  30028.                 @type = 12, 
  30029.                 @article_id = @article_id, 
  30030.                 @command_id = @command_id, 
  30031.                 @partial_command = @partial_cmdbit, 
  30032.                 @command = @binary_cmd
  30033.             if (@@ERROR != 0 or @retcode != 0)
  30034.                 GOTO UNDO
  30035.         end -- end of while loop
  30036.     end     -- end of if (@mode = @mode_insdistcmd)
  30037.  
  30038.     --
  30039.     -- Command(s) added successfully - End Tran
  30040.     --
  30041.     commit tran sp_MSadd_compensating_cmd
  30042.     return (0)
  30043.  
  30044. UNDO:
  30045.     --
  30046.     -- Error - Rollback
  30047.     --
  30048.     IF (@@TRANCOUNT > 0)
  30049.     begin
  30050.         ROLLBACK TRAN sp_MSadd_compensating_cmd
  30051.         if (@@TRANCOUNT > 0)
  30052.             COMMIT TRAN   
  30053.     end
  30054.     return (1)    
  30055. END
  30056. go
  30057. EXEC dbo.sp_MS_marksystemobject sp_MSadd_compensating_cmd
  30058. GO
  30059.  
  30060. --
  30061. --  System UDF fn_varbintohexstr
  30062. --     This function takes as input a varbinary
  30063. --    and returns the Hexadecimal representation string
  30064. --
  30065. create function dbo.fn_varbintohexstr (
  30066.     @pbinin varbinary(8000) )
  30067. returns nvarchar(4000)
  30068. as
  30069. begin
  30070.     declare @pstrout nvarchar(4000)
  30071.  
  30072.     select @pstrout = master.dbo.fn_varbintohexsubstring(1,@pbinin,1,0)
  30073.     return @pstrout
  30074. end
  30075. go
  30076.  
  30077. --
  30078. --  System UDF fn_varbintohexsubstring
  30079. --     This function takes as input a varbinary, and start offset and length
  30080. --    and returns the Hexadecimal representation string for the given substring
  30081. --
  30082. create function dbo.fn_varbintohexsubstring (
  30083.     @fsetprefix bit = 1        -- append '0x' to the output
  30084.     ,@pbinin varbinary(8000) -- input binary stream
  30085.     ,@startoffset int = 1     -- starting offset 
  30086.     ,@cbytesin int = 0         -- length of input to consider, 0 means total length
  30087. )
  30088. returns nvarchar(4000)
  30089. as
  30090. begin
  30091.     declare @pstrout nvarchar(4000)
  30092.         ,@i int
  30093.         ,@firstnibble int
  30094.         ,@secondnibble int
  30095.         ,@tempint int
  30096.         ,@hexstring char(16)
  30097.  
  30098.     --
  30099.     -- initialize and validate
  30100.     --
  30101.     if (@pbinin IS NOT NULL)
  30102.     begin    
  30103.         select @i = 0
  30104.                 ,@cbytesin = case when (@cbytesin > 0) then @cbytesin else DATALENGTH(@pbinin) end
  30105.                 ,@pstrout =  case when (@fsetprefix = 1) then N'0x' else N'' end
  30106.                 ,@hexstring = '0123456789abcdef'
  30107.  
  30108.         if ( ((@cbytesin * 2) + 2 > 4000) or ((@cbytesin * 2) + 2 < 1) )
  30109.             return NULL
  30110.  
  30111.         if ( ( @startoffset > @cbytesin ) or ( @startoffset < 1 ) )
  30112.             return NULL
  30113.             
  30114.         --
  30115.         -- do for each byte
  30116.         --
  30117.         while (@i < @cbytesin)
  30118.         begin
  30119.             --
  30120.             -- Each byte has two nibbles
  30121.             -- which we convert to character
  30122.             --
  30123.             select @tempint = cast(substring(@pbinin, @i + @startoffset, 1) as int)
  30124.             select @firstnibble = @tempint / 16
  30125.             select @secondnibble = @tempint % 16
  30126.  
  30127.             --
  30128.             -- we need to do an explicit cast with substring 
  30129.             -- for proper string conversion. 
  30130.             --
  30131.             select @pstrout = @pstrout +
  30132.                 cast(substring(@hexstring, (@firstnibble+1), 1) as nvarchar) +
  30133.                 cast(substring(@hexstring, (@secondnibble+1), 1) as nvarchar)
  30134.  
  30135.             select @i = @i + 1
  30136.         end
  30137.     end
  30138.     
  30139.     -- All done
  30140.     return @pstrout
  30141. end
  30142. go
  30143.  
  30144. -- system function : returns string corresponding to version number part of setup path
  30145. -- for the current instance 
  30146. raiserror(15339,-1,-1,'fn_MSsharedversion')
  30147. GO
  30148. CREATE FUNCTION dbo.fn_MSsharedversion ( @len_minorversion tinyint = 1 )
  30149.     RETURNS NVARCHAR(10)
  30150. AS
  30151. BEGIN
  30152.     
  30153.     DECLARE @version VARCHAR(20), @bookmark_begin SMALLINT, @bookmark_end SMALLINT
  30154.     DECLARE @tools_ver VARCHAR(20)
  30155.  
  30156.     SELECT @version = CONVERT( VARCHAR(20), SERVERPROPERTY( N'PRODUCTVERSION') )
  30157.  
  30158.      SELECT @bookmark_begin = CHARINDEX( '-', @version, 1) + 1
  30159.     SELECT @bookmark_end = CHARINDEX( '.', @version, @bookmark_begin + 3 ) 
  30160.     SELECT @version = SUBSTRING( @version, @bookmark_begin, @bookmark_end - @bookmark_begin )
  30161.  
  30162.     SELECT @tools_ver = RTRIM(LTRIM(LEFT( @version, CHARINDEX('.', @version, 1) - 1 ) + LEFT(RIGHT( @version, CHARINDEX('.', @version, @len_minorversion ) ), @len_minorversion )))
  30163.  
  30164.     RETURN @tools_ver
  30165.  
  30166. END
  30167. GO
  30168.  
  30169.  
  30170. -- system procedure : Get install and data root paths (instance aware)
  30171. raiserror(15339,-1,-1,'sp_MSget_setup_paths')
  30172. GO
  30173. CREATE PROCEDURE sp_MSget_setup_paths (
  30174. @sql_path    NVARCHAR(260) = NULL OUTPUT, 
  30175. @data_path    NVARCHAR(260) = NULL OUTPUT )
  30176. AS
  30177. BEGIN
  30178.     
  30179.     DECLARE @retcode INTEGER
  30180.     DECLARE @regkey NVARCHAR(260)
  30181.     
  30182.     SET NOCOUNT ON 
  30183.     
  30184.     declare @instance sysname
  30185.     select @instance = convert(sysname, SERVERPROPERTY('InstanceName'))
  30186.     select @regkey = 'SOFTWARE\Microsoft\'
  30187.     -- default installation
  30188.     if @instance is null
  30189.         SELECT @regkey = @regkey + 'MSSQLServer\Setup' 
  30190.     else
  30191.         SELECT @regkey = @regkey + 'Microsoft SQL Server\' + @instance + '\Setup'
  30192.  
  30193.     EXECUTE @retcode = master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', 
  30194.         @regkey,
  30195.         'SQLPath',
  30196.         @param = @sql_path OUTPUT
  30197.  
  30198.     IF ( @retcode <> 0 ) or ( @@ERROR <> 0 ) 
  30199.         RETURN (1)
  30200.     
  30201.     EXECUTE @retcode = master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', 
  30202.         @regkey,
  30203.         'SQLDataRoot',
  30204.         @param = @data_path OUTPUT
  30205.  
  30206.     IF ( @retcode <> 0 ) or ( @@ERROR <> 0 ) 
  30207.         RETURN (1)
  30208.  
  30209.     RETURN (0)
  30210.  
  30211. END
  30212. GO
  30213.  
  30214. -- No parameter checking is performed in sp_MSremoveoffloadparameter
  30215. raiserror(15339,-1,-1,'sp_MSremoveoffloadparameter')
  30216. GO
  30217. CREATE PROCEDURE sp_MSremoveoffloadparameter (
  30218.     @job_id    VARBINARY(16),
  30219.     @agenttype NVARCHAR(20) 
  30220.     ) AS
  30221.     SET NOCOUNT ON
  30222.     
  30223.     /*
  30224.     ** Declarations
  30225.     */
  30226.     
  30227.     DECLARE @paramstart    INT
  30228.     DECLARE @paramend      INT
  30229.     DECLARE @paramlen      INT
  30230.     DECLARE @paramend2     INT
  30231.     DECLARE @command       NVARCHAR(3200) 
  30232.     DECLARE @commandtail   NVARCHAR(3200)
  30233.     DECLARE @pattern       NVARCHAR(100)
  30234.  
  30235.     SELECT @pattern = N'%-[Oo][Ff][Ff][Ll][Oo][Aa][Dd]%'
  30236.     SELECT @paramlen = LEN(N'-offload')
  30237.     SELECT @command = NULL
  30238.  
  30239.     -- use the job_id and the agent type to retrieve the agent command
  30240.     -- line, only one agent command step is allowed in a job
  30241.  
  30242.     SELECT @command = command FROM msdb.dbo.sysjobsteps 
  30243.      WHERE job_id = @job_id AND LOWER(subsystem collate SQL_Latin1_General_CP1_CS_AS) = LOWER(@agenttype collate SQL_Latin1_General_CP1_CS_AS)
  30244.  
  30245.     -- purge all instances of '-offload servername' from the agent command line
  30246.     SELECT @paramstart = PATINDEX(@pattern, @command)
  30247.     WHILE ((@command IS NOT NULL) AND (@paramstart <> 0))
  30248.     BEGIN       
  30249.         -- extract the part of the command line after the -Offload parameter
  30250.         SELECT @commandtail = SUBSTRING(@command, @paramstart + @paramlen, 
  30251.                                         LEN(@command) - 
  30252.                                         (@paramstart + @paramlen) + 1)
  30253.  
  30254.         -- search for the beginning of the server name that follows -offload
  30255.         -- in the command tail; note that the empty spaces in the square
  30256.         -- bracket of the pattern are actually a space and a tab
  30257.  
  30258.         SELECT @paramend = PATINDEX(N'%[^     ]%', @commandtail)
  30259.  
  30260.         -- search for the end of the server name that follows -offload
  30261.         IF (@paramend <> 0) 
  30262.         BEGIN
  30263.             SELECT @commandtail = SUBSTRING(@commandtail, @paramend, 
  30264.                                             LEN(@commandtail) - @paramend + 1)
  30265.             SELECT @paramend2 = PATINDEX(N'%[     ]%', @commandtail) 
  30266.             IF (@paramend2 <> 0)
  30267.             BEGIN
  30268.                 SELECT @paramend = @paramend + @paramend2 - 1
  30269.             END
  30270.             ELSE
  30271.             BEGIN
  30272.                 -- reaching the end of the command line
  30273.                 SELECT @paramend = @paramend + LEN(@commandtail) - 1
  30274.                 IF @paramstart > 1 
  30275.                 BEGIN
  30276.                     SELECT @paramstart = @paramstart - 1
  30277.                     SELECT @paramend = @paramend + 1
  30278.                 END
  30279.             END
  30280.         
  30281.         END                
  30282.         -- Remove the -Offload parameter from the command line
  30283.         SELECT @command = STUFF(@command, @paramstart, @paramlen + @paramend, N'')
  30284.  
  30285.         SELECT @paramstart = PATINDEX(@pattern, @command)
  30286.     END
  30287.     
  30288.     -- update the agent command line with all the -offload's removed
  30289.     UPDATE msdb.dbo.sysjobsteps 
  30290.        SET command = @command
  30291.      WHERE job_id = @job_id AND LOWER(subsystem collate SQL_Latin1_General_CP1_CS_AS) = LOWER(@agenttype collate SQL_Latin1_General_CP1_CS_AS)   
  30292.     
  30293.     RETURN 0
  30294. GO
  30295. EXEC dbo.sp_MS_marksystemobject sp_MSremoveoffloadparameter
  30296. GO
  30297.  
  30298. -- No parameter checking is performed in sp_MSaddoffloadparameter 
  30299. raiserror(15339,-1,-1,'sp_MSaddoffloadparameter')
  30300. GO
  30301. CREATE PROCEDURE sp_MSaddoffloadparameter (
  30302.     @offloadserver sysname, /* Name of the target server to offload the agent to */
  30303.     @job_id        VARBINARY(16), 
  30304.     @agenttype     NVARCHAR(20) /* Agent type can either be 'merge' or 'distribution' */
  30305.     ) AS
  30306.     
  30307.     SET NOCOUNT ON
  30308.  
  30309.     /*
  30310.     **  Declarations
  30311.     */
  30312.  
  30313.     DECLARE @command               NVARCHAR(3200)
  30314.     
  30315.     -- initialize variables
  30316.     SELECT @command = NULL    
  30317.  
  30318.     -- call sp_MSremoveoffloadparameter to remove all exisiting instances of the 
  30319.     -- -offload parameters from the agent command line; the return status
  30320.     -- of sp_MSremoveoffloadparameter is ignored
  30321.     EXEC sp_MSremoveoffloadparameter @job_id=@job_id, @agenttype=@agenttype
  30322.     
  30323.     -- update the agent command line by appending '-Offload ' + 
  30324.     -- @offloadserver    
  30325.     
  30326.     UPDATE msdb.dbo.sysjobsteps
  30327.        SET command = command + N' -Offload ' + @offloadserver 
  30328.      WHERE job_id = @job_id 
  30329.        AND LOWER(subsystem collate SQL_Latin1_General_CP1_CS_AS) = LOWER(@agenttype collate SQL_Latin1_General_CP1_CS_AS)
  30330.          
  30331.     RETURN 0
  30332. GO
  30333. EXEC dbo.sp_MS_marksystemobject sp_MSaddoffloadparameter
  30334. GO
  30335.  
  30336. --
  30337. --  System UDF fn_MSgensqescstr
  30338. --     This function takes as input a varchar
  30339. --    and stuffs an extra single quote for any single quotes in the string
  30340. --
  30341. raiserror(15339,-1,-1,'fn_MSgensqescstr')
  30342. go
  30343. create function dbo.fn_MSgensqescstr (
  30344.     @pstrin nvarchar(4000) )
  30345. returns nvarchar(4000)
  30346. as
  30347. begin
  30348.     declare @pstrout nvarchar(4000)
  30349.  
  30350.     select @pstrout = REPLACE(@pstrin, N'''', N'''''')
  30351.     return @pstrout
  30352. end
  30353. go
  30354.  
  30355. raiserror(15339,-1,-1,'sp_MSUpgradeConflictTable')
  30356. GO
  30357. create proc sp_MSUpgradeConflictTable
  30358.     @skip_procgen bit = 0
  30359. AS
  30360. declare @retcode int
  30361. declare @conflict_table sysname
  30362. declare @pubid uniqueidentifier 
  30363. declare @artid uniqueidentifier 
  30364. declare @ins_conflict_proc sysname
  30365. declare @conflict_id    int
  30366. declare @objid            int
  30367. declare @qual_conflict    nvarchar(132)
  30368.  
  30369.  
  30370. if exists( select * from sysobjects where name = 'MSmerge_delete_conflicts' ) and 
  30371.     not exists (select * from syscolumns where id = object_id('MSmerge_delete_conflicts') and name = 'create_time')
  30372. begin
  30373.     alter table MSmerge_delete_conflicts add create_time datetime not null default getdate()
  30374. end
  30375.  
  30376. declare AC CURSOR LOCAL FAST_FORWARD for select conflict_table, objid, ins_conflict_proc, pubid, artid from sysmergearticles 
  30377. open AC
  30378. fetch AC into @conflict_table, @objid, @ins_conflict_proc, @pubid, @artid
  30379. while (@@fetch_status<>-1)
  30380. begin
  30381.     if @conflict_table is NOT null
  30382.     begin
  30383.         select @conflict_id = object_id(@conflict_table)
  30384.         select @qual_conflict=QUOTENAME(@conflict_table)
  30385.         /*
  30386.         ** Upgrade conflict table so that it can get cleaned up later on
  30387.         */
  30388.         if @conflict_id is not NULL and not exists (select name from syscolumns where name='MSrepl_create_time' and id=@conflict_id)
  30389.         begin
  30390.             exec ('alter table ' + @qual_conflict + ' add MSrepl_create_time datetime not null default getdate() ')
  30391.             if @@ERROR<>0
  30392.             begin
  30393.                 close AC
  30394.                 deallocate AC
  30395.                 return (1)
  30396.             end
  30397.             /*
  30398.             ** use create_time value for the new column before dropping create_time column, after making 
  30399.             ** sure create_time is not from user table.
  30400.             */
  30401.             if exists (select name from syscolumns where name='create_time' and id=@conflict_id) and
  30402.                 not exists (select name from syscolumns where name='create_time' and id=@objid) 
  30403.             begin
  30404.                 exec ('update ' + @qual_conflict + ' set MSrepl_create_time=create_time')
  30405.                 if @@ERROR<>0
  30406.                 begin
  30407.                     close AC
  30408.                     deallocate AC
  30409.                     return (1)
  30410.                 end
  30411.                 declare @colid                     int
  30412.                 declare @default_constraint        sysname
  30413.                 
  30414.                 select @colid = colid from syscolumns where name='create_time' and id=@conflict_id
  30415.                 select @default_constraint=object_name(constid) from sysconstraints where id=@conflict_id and colid=@colid
  30416.                 /*
  30417.                 ** drop default constrait on create_time column
  30418.                 */
  30419.                 if @default_constraint is not NULL
  30420.                 begin
  30421.                     exec ('alter table ' + @qual_conflict + ' drop constraint ' + @default_constraint)
  30422.                     if @@ERROR<>0
  30423.                     begin
  30424.                         close AC
  30425.                         deallocate AC
  30426.                         return (1)
  30427.                     end
  30428.                 end
  30429.                 
  30430.                 exec ('alter table ' + @qual_conflict + ' drop column create_time')
  30431.                 if @@ERROR<>0
  30432.                 begin
  30433.                     close AC
  30434.                     deallocate AC
  30435.                     return (1)
  30436.                 end
  30437.             end
  30438.             if @ins_conflict_proc is not NULL and object_id(@ins_conflict_proc) is not NULL 
  30439.             begin
  30440.                 exec ('drop procedure ' + @ins_conflict_proc)
  30441.                 if @@ERROR<>0
  30442.                 begin
  30443.                     close AC
  30444.                     deallocate AC            
  30445.                     return (1)
  30446.                 end
  30447.                 --force to regenerate conflict insert proc to pick up the new column name
  30448.                 update sysmergearticles set ins_conflict_proc=NULL where artid=@artid and pubid=@pubid
  30449.                 if @@ERROR<>0
  30450.                 begin
  30451.                     close AC
  30452.                     deallocate AC            
  30453.                     return (1)
  30454.                 end
  30455.  
  30456.                 -- Do not upgrade conflict tables if this is called from sp_restoredbreplication, as 
  30457.                 -- the entire replication will be striped out.
  30458.                 if @skip_procgen = 0
  30459.                 begin
  30460.                     exec @retcode = sp_MSgetconflictinsertproc @artid, @pubid, 0     
  30461.                     if @@ERROR<>0 or @retcode<>0
  30462.                     begin
  30463.                         close AC
  30464.                         deallocate AC            
  30465.                         return (1)
  30466.                     end
  30467.                 end
  30468.             end
  30469.         end
  30470.  
  30471.         if not exists (select * from sysindexes where id = @conflict_id and keys is not null)
  30472.         begin
  30473.             declare @rgcol sysname
  30474.             declare @indname sysname
  30475.             declare @quotedname sysname
  30476.             declare @owner sysname
  30477.             
  30478.             select @owner=user_name(uid) from sysobjects where id = @objid
  30479.             select @rgcol = QUOTENAME(name) from syscolumns where id = @objid and
  30480.                     ColumnProperty(id, name, 'isrowguidcol') = 1
  30481.             select @indname = 'uc_' + @conflict_table
  30482.             set @indname = QUOTENAME(@indname)
  30483.             set @quotedname = QUOTENAME(@owner) + '.' + QUOTENAME(@conflict_table)
  30484.             exec ('Create unique clustered index ' + @indname + ' on ' + @quotedname +
  30485.                 ' (' + @rgcol + ', origin_datasource)' )
  30486.             if @@ERROR <> 0
  30487.             begin
  30488.                 close AC
  30489.                 deallocate AC            
  30490.                 return (1)
  30491.             end
  30492.         end
  30493.     end
  30494.     fetch next from AC into @conflict_table, @objid, @ins_conflict_proc, @pubid, @artid
  30495. end
  30496. close AC
  30497. deallocate AC
  30498. return (0)
  30499. GO
  30500. exec dbo.sp_MS_marksystemobject sp_MSUpgradeConflictTable
  30501. Go
  30502.  
  30503. --
  30504. -- This SP is used by the queued tran triggers to insert data into the SQL queue
  30505. -- it enforces the security check and does the insert into the queue table
  30506. -- Note this transaction is always called with a transaction (local or distributed)
  30507. -- so do not add any save tran semantics
  30508. --
  30509. raiserror(15339,-1,-1,'sp_MSsendtosqlqueue')
  30510. GO
  30511. go
  30512. create proc sp_MSsendtosqlqueue (
  30513.     @objid int
  30514.     ,@publisher sysname
  30515.     ,@publisher_db sysname
  30516.     ,@publication sysname
  30517.     ,@owner sysname
  30518.     ,@tranid sysname
  30519.     ,@data varbinary(8000)
  30520.     ,@datalen int
  30521.     ,@commandtype int = 1
  30522.     ,@cmdstate bit = 0
  30523. )
  30524. as
  30525. begin
  30526.     set nocount on
  30527.     --
  30528.     -- Security check
  30529.     -- Make sure this proc is infact being called from the given object(trigger)
  30530.     -- 
  30531.     if (trigger_nestlevel(@objid) = 0)
  30532.     begin
  30533.         raiserror(14126, 16, 2)
  30534.         return 1
  30535.     end
  30536.     --
  30537.     -- Security check: the caller of this SP has to be one of the 
  30538.     -- predefined replication objects for this subscription
  30539.     --
  30540.     if (@objid not in (select object_id(quotename(@owner) + N'.' + quotename(object_name)) 
  30541.         from dbo.MSreplication_objects
  30542.         where publisher = @publisher and publisher_db = @publisher_db and
  30543.                 publication = @publication and object_type = 'T'))
  30544.     begin
  30545.         raiserror(14126, 16, 3)
  30546.         return 1
  30547.     end
  30548.     --
  30549.     -- insert into the queue table
  30550.     --
  30551.     insert into dbo.MSreplication_queue with (rowlock) (publisher,publisher_db,publication,tranid,data,datalen,commandtype,cmdstate)
  30552.         values(UPPER(@publisher),@publisher_db,@publication,@tranid,@data,@datalen,@commandtype,@cmdstate)
  30553.     if (@@error != 0)
  30554.         return 1
  30555.     --
  30556.     -- Update MSrepl_queuedtraninfo
  30557.     --
  30558.     if exists (select *
  30559.         from dbo.MSrepl_queuedtraninfo with (nolock)
  30560.         where publisher = UPPER(@publisher) 
  30561.             and publisher_db = @publisher_db 
  30562.             and publication = @publication
  30563.             and tranid = @tranid)
  30564.     begin
  30565.         --
  30566.         -- row for this transaction exists - update it
  30567.         --
  30568.         update dbo.MSrepl_queuedtraninfo with (rowlock)
  30569.         set maxorderkey = @@identity
  30570.             ,commandcount = commandcount + 1
  30571.         where publisher = UPPER(@publisher)
  30572.             and publisher_db = @publisher_db 
  30573.             and publication = @publication
  30574.             and tranid = @tranid
  30575.     end
  30576.     else
  30577.     begin
  30578.         --
  30579.         -- row for this transaction does not exist - insert it
  30580.         --
  30581.         insert into dbo.MSrepl_queuedtraninfo with (rowlock) (publisher,publisher_db,publication,tranid,maxorderkey,commandcount)
  30582.         values (UPPER(@publisher),@publisher_db,@publication,@tranid,@@identity,1)
  30583.     end
  30584.     if (@@error != 0)
  30585.         return 1
  30586.     --
  30587.     -- all done
  30588.     --
  30589.     return 0
  30590. end
  30591. go
  30592. exec dbo.sp_MS_marksystemobject sp_MSsendtosqlqueue
  30593. go            
  30594.  
  30595. /*
  30596. ** One and only one of these two parameters needs to be specified - meaning adjust publisher side
  30597. ** identity range at publication level (all tables) or table level (whose name is given)
  30598. */
  30599.  
  30600. raiserror(15339,-1,-1,'sp_adjustpublisheridentityrange')
  30601. GO
  30602. create procedure sp_adjustpublisheridentityrange (
  30603.     @publication    sysname = NULL,
  30604.     @table_name         sysname = NULL,
  30605.     @table_owner    sysname = NULL
  30606. )
  30607. AS
  30608. set nocount on
  30609.  
  30610. declare @retcode                 int, @object_found bit
  30611. declare @objid                    int
  30612. declare @qualified_table_name    nvarchar(260)
  30613. declare @identity_support        int
  30614. declare @pubid                    uniqueidentifier
  30615.  
  30616. select @object_found = 0
  30617.  
  30618. /*
  30619. ** Security Check
  30620. */
  30621. EXEC @retcode = dbo.sp_MSreplcheck_publish
  30622. IF @@ERROR <> 0 or @retcode <> 0
  30623.     return (1)
  30624.  
  30625. if ((@publication is NULL and @table_name is NULL) or 
  30626.         (@publication is NULL and @table_name is NULL) or
  30627.         (@publication is not NULL and @table_name is not NULL))
  30628. begin
  30629.     raiserror(21314, 16, -1, '@publication', '@table_name')
  30630.     return (1)
  30631. end
  30632.  
  30633. if @publication is NULL
  30634. begin
  30635.     if @table_owner is NULL
  30636.         select @table_owner = user_name()
  30637.     select @qualified_table_name = QUOTENAME(@table_owner) + '.' + QUOTENAME(@table_name)
  30638.     
  30639.     select @objid = object_id(@qualified_table_name)
  30640.     if @objid is NULL
  30641.     begin 
  30642.         RAISERROR (14027, 11, -1, @qualified_table_name)
  30643.         return (1)
  30644.     end
  30645. end
  30646.  
  30647. --Do this for merge?
  30648. if exists (select * from sysobjects where name = 'sysmergepublications')
  30649. begin
  30650.     if @publication is NULL
  30651.     begin
  30652.         select @identity_support = identity_support from sysmergearticles where objid=@objid
  30653.         if @identity_support is not null
  30654.         begin
  30655.             select @object_found = 1
  30656.             if @identity_support = 0
  30657.                 return (0)
  30658.             exec @retcode = sp_MSadjustmergeidentity @tablename=@table_name    
  30659.             if @retcode<>0 or @@ERROR<>0
  30660.             begin
  30661.                 raiserror(21315, 16, -1, @table_name)
  30662.                 return (1)
  30663.             end
  30664.         end
  30665.     end
  30666.  
  30667.     if @table_name is NULL
  30668.     begin
  30669.         select @pubid=pubid FROM sysmergepublications
  30670.             WHERE name = @publication and UPPER(publisher)=UPPER(@@servername) and publisher_db=db_name()
  30671.         if @pubid is not null
  30672.         begin
  30673.             select @object_found = 1
  30674.             if not exists (select * from sysmergearticles where pubid=@pubid and identity_support=1)
  30675.                 return (0)
  30676.             exec @retcode = sp_MSadjustmergeidentity @publication=@publication
  30677.             if @retcode<>0 or @@ERROR<>0
  30678.             begin
  30679.                 raiserror(21316, 16, -1, @publication)
  30680.                 return (1)
  30681.             end    
  30682.         end    
  30683.     end
  30684. end
  30685.  
  30686. if exists (select * from sysobjects where name = 'syspublications')
  30687. begin
  30688.     if @publication is NULL
  30689.     begin
  30690.         declare @artid int
  30691.         select top 1 @artid = artid from sysarticles where 
  30692.             objid = @objid
  30693.         if @artid is not null
  30694.         begin
  30695.             select @object_found = 1
  30696.             exec @retcode = sp_MSpub_adjust_identity @artid
  30697.             if @retcode<>0 or @@ERROR<>0
  30698.                 return (1)
  30699.         end
  30700.     end
  30701.     else
  30702.     begin
  30703.         declare @publication_id int
  30704.         select @publication_id = pubid from syspublications where name = @publication
  30705.         if @publication_id is not null
  30706.         begin
  30707.             select @object_found = 1
  30708.             DECLARE adjust_identity CURSOR LOCAL FAST_FORWARD FOR
  30709.                 SELECT art1.objid
  30710.                   FROM sysarticles art1,
  30711.                        sysarticleupdates art2
  30712.                   where art1.pubid = @publication_id and
  30713.                         art1.artid = art2.artid and
  30714.                         art2.identity_support = 1 and
  30715.                         (art1.artid = @artid or @artid is null)
  30716.             FOR READ ONLY
  30717.  
  30718.             OPEN adjust_identity        
  30719.             FETCH adjust_identity INTO @objid
  30720.             WHILE (@@fetch_status <> -1)
  30721.             begin
  30722.                 exec @retcode = sp_MSpub_adjust_identity @artid
  30723.                 if @retcode<>0 or @@ERROR<>0
  30724.                     return (1)
  30725.                 FETCH adjust_identity INTO @objid
  30726.             end
  30727.         end
  30728.     end
  30729. end
  30730. if @object_found = 0
  30731. begin
  30732.     if @publication is null
  30733.         raiserror(21246, 16, -1, @qualified_table_name)
  30734.     else
  30735.         RAISERROR (20026, 11, -1, @publication)
  30736. end
  30737.  
  30738. RETURN (0)
  30739. GO
  30740. exec dbo.sp_MS_marksystemobject sp_adjustpublisheridentityrange
  30741. GO            
  30742.  
  30743. grant execute on dbo.sp_adjustpublisheridentityrange to public
  30744. GO
  30745.  
  30746. -- sp_MSestimate(merge)snapshotworkload is called exclusively by the 
  30747. -- snapshot agent to estimate the amount of work that has to be done for
  30748. -- a snapshot session and a breakdown of the work load into subtasks
  30749.  
  30750. raiserror(15339,-1,-1,'sp_MSestimatemergesnapshotworkload')
  30751. GO
  30752. create proc sp_MSestimatemergesnapshotworkload (
  30753.     @publication sysname
  30754.     )
  30755. as
  30756. begin
  30757.     set nocount on
  30758.  
  30759.     declare @taskload                       int
  30760.     declare @bigtaskload                    bigint
  30761.     declare @table_created                  bit
  30762.     declare @retcode                        int
  30763.  
  30764.     -- constant
  30765.     declare @zerouuid                       uniqueidentifier
  30766.     select @zerouuid = convert(uniqueidentifier, N'{00000000-0000-0000-0000-000000000000}')
  30767.     -- Publication info
  30768.     declare @pubid                          uniqueidentifier
  30769.     declare @compress_snapshot              bit
  30770.     declare @snapshot_in_defaultfolder      bit
  30771.     declare @alt_snapshot_folder            nvarchar(255)
  30772.     declare @enabled_for_internet           bit
  30773.     declare @ftp_password                   nvarchar(524) 
  30774.     declare @ftp_subdirectory               nvarchar(255)
  30775.     declare @pre_snapshot_script            nvarchar(255)
  30776.     declare @post_snapshot_script           nvarchar(255)    
  30777.     declare @dynamic_filters                bit
  30778.  
  30779.     -- Per publication summary stats
  30780.     declare @numarticles                    int
  30781.     declare @totalrowcount                  int   
  30782.     declare @needsysprescript               bit
  30783.     declare @copysnapshot                   bit
  30784.     declare @deletefiles                    bit
  30785.     declare @scriptproccost                 int
  30786.     declare @addcommandstotal               int
  30787.     declare @numscripts                     int
  30788.     declare @totalbcpcostper100             int
  30789.     declare @numprescriptcommands           int 
  30790.     declare @numunsyncedarticles            int
  30791.     declare @numtablearticles               int
  30792.     declare @systablesrowcount              int
  30793.     declare @maxint                         int
  30794.  
  30795.     select @numarticles = 0
  30796.     select @totalrowcount = 0
  30797.     select @needsysprescript = 0
  30798.     select @copysnapshot = 0
  30799.     select @deletefiles = 0
  30800.     select @scriptproccost = 0
  30801.     select @deletefiles = 0
  30802.     select @addcommandstotal = 0
  30803.     select @numscripts = 0
  30804.     select @totalbcpcostper100 = 0
  30805.     select @numprescriptcommands = 0
  30806.     select @numunsyncedarticles = 0
  30807.     select @numtablearticles = 0
  30808.     select @systablesrowcount = 0
  30809.     select @maxint = 2147483647
  30810.  
  30811.     -- Per article variables
  30812.     declare @artid                          uniqueidentifier
  30813.     declare @schema_option                  int
  30814.     declare @creation_script                nvarchar(255)
  30815.     declare @type                           tinyint
  30816.     declare @objid                          int
  30817.     declare @rowcount                       int
  30818.     declare @name                           sysname
  30819.     declare @status                         int
  30820.  
  30821.  
  30822.     -- Security check
  30823.     select @retcode = 0
  30824.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  30825.     IF @@ERROR <> 0 or @retcode <> 0
  30826.         return (1)
  30827.  
  30828.     select @table_created = 0
  30829.  
  30830.     select @pubid = null
  30831.     select @compress_snapshot = 0
  30832.     select @snapshot_in_defaultfolder = 0
  30833.     select @alt_snapshot_folder = null
  30834.     select @enabled_for_internet = 0
  30835.     select @ftp_password = null
  30836.     select @ftp_subdirectory = null
  30837.     select @pre_snapshot_script = null
  30838.     select @post_snapshot_script = null
  30839.     -- Validate publication and retrieve publication information 
  30840.     select @pubid = pubid, 
  30841.            @compress_snapshot = compress_snapshot,
  30842.            @snapshot_in_defaultfolder = snapshot_in_defaultfolder,
  30843.            @alt_snapshot_folder = alt_snapshot_folder,
  30844.            @enabled_for_internet = enabled_for_internet,
  30845.            @ftp_password = ftp_password,
  30846.            @ftp_subdirectory = ftp_subdirectory,
  30847.            @pre_snapshot_script = pre_snapshot_script,
  30848.            @post_snapshot_script = post_snapshot_script,
  30849.            @dynamic_filters = dynamic_filters
  30850.            from sysmergepublications
  30851.      where name = @publication
  30852.        and upper(@@servername) = publisher
  30853.        and publisher_db = db_name()
  30854.     if @pubid = null
  30855.     begin   
  30856.         raiserror(20026, 11, -1, @publication)
  30857.         return (1)
  30858.     end
  30859.  
  30860.     -- An artid of -1 means the task is a per publication
  30861.     -- task
  30862.  
  30863.     -- Task id mapping - This is the list of task whose completion can be 
  30864.     -- reported by the snapshot agent
  30865.     -- 0 - Total workload (not really a task)
  30866.     -- 1 - Schema script generation
  30867.     -- 2 - Trigger script generation 
  30868.     -- 3 - XProp script generation
  30869.     -- 4 - Bcp file generation
  30870.     -- 5 - Activating subscription (estimate number of subscriptions?)
  30871.     -- 6 - Adding snapshot commands
  30872.     -- 7 - System pre-script generation
  30873.     -- 8 - Flushing folder for scripts
  30874.     -- 9 - Constraint script generation
  30875.     -- 10 - Copying pre-script
  30876.     -- 11 - Copying post-script
  30877.     -- 12 - Copying custom schema creation script
  30878.     -- 13 - Index script generation
  30879.     -- 14 - Flushing the cabinet
  30880.     -- 15 - Adding rowguid column
  30881.     -- 16 - Setting article procs
  30882.     -- 17 - Adding merge triggers
  30883.     -- 18 - Generating system table scripts
  30884.     -- 19 - Generating system table bcp files
  30885.     -- 20 - Making publication generation
  30886.     -- 21 - Generating and setting conflict script
  30887.     -- 22 - Generating publication views
  30888.     
  30889.     -- Weights and overheads
  30890.     -- DMO Script generation - 7/script
  30891.     -- BCP 5 overhead + 5/100 rows
  30892.     -- Flush folder for bcp 2/100 rows
  30893.     -- Delete file 2
  30894.     -- System pre-snapshot script 1 overhead + 0.5/pre-creation command
  30895.     -- Copying user file 2
  30896.     -- Adding file to cabinet 1 for scripts and 1/100 rows in bcp file
  30897.     -- Loading article info 3
  30898.     -- Delete bcp file 2/100rows 
  30899.     -- Copy bcp file  2/100rows  
  30900.     -- Flush scripts folder 1/2 scripts
  30901.     -- Flushing cabinet per 5 scripts 1
  30902.     -- Flushing cabinet per 500 rows 1
  30903.     -- Script execution 3
  30904.     -- Adding rowguid columns 20/100 rows
  30905.     -- Adding merge triggers 7
  30906.     -- Setting article procs 5
  30907.  
  30908.     -- Here is the list of cost factors 
  30909.     declare @addcommandcost     int
  30910.     declare @dmoscriptcost      int
  30911.     declare @bcpoverhead        int
  30912.     declare @bcpcostper100      int
  30913.     declare @flushper100        int
  30914.     declare @flushperscript     int
  30915.     declare @delfilecost        int
  30916.     declare @syspreoverhead     int
  30917.     declare @syspreper2commands int
  30918.     declare @addbcptocabper100  int
  30919.     declare @addscripttocab     int
  30920.     declare @copyfilecost       int
  30921.     declare @loadartinfo        int    
  30922.     declare @deletebcpper100    int
  30923.     declare @copybcpper100      int
  30924.     declare @flushper2scripts   int
  30925.     declare @flushcabper5scripts int
  30926.     declare @flushcabper500bcprows int
  30927.     declare @scriptexeccost int
  30928.     declare @rowguidper100 int
  30929.     declare @addmergetriggers int
  30930.     declare @setartprocs int
  30931.     declare @pubviewperarticle int
  30932.     declare @genperarticle int
  30933.  
  30934.     select @addcommandcost = 2
  30935.     select @dmoscriptcost = 7
  30936.     select @bcpcostper100 = 20
  30937.     select @bcpoverhead = 2
  30938.     select @flushper100 = 2
  30939.     select @flushperscript = 3
  30940.     select @delfilecost = 2
  30941.     select @syspreoverhead = 1
  30942.     select @syspreper2commands = 1
  30943.     select @addbcptocabper100 = 1
  30944.     select @addscripttocab = 1
  30945.     select @copyfilecost = 2
  30946.     select @loadartinfo = 3    
  30947.     select @deletebcpper100 = 1
  30948.     select @copybcpper100 = 2
  30949.     select @flushper2scripts = 1
  30950.     select @flushcabper5scripts = 1
  30951.     select @flushcabper500bcprows = 1
  30952.     select @scriptexeccost = 3
  30953.     select @rowguidper100 = 20
  30954.     select @addmergetriggers = 3
  30955.     select @pubviewperarticle = 2
  30956.     select @genperarticle = 2
  30957.     select @setartprocs = 5
  30958.  
  30959.     create table #workload_breakdown
  30960.     (
  30961.         name        sysname collate database_default,
  30962.         artid       uniqueidentifier,
  30963.         taskid      int,
  30964.         taskload    int
  30965.     )
  30966.     if @@error <> 0
  30967.         goto Failure
  30968.  
  30969.     select @table_created = 1
  30970.  
  30971.     -- Per publication work load estimate that can be done using publication
  30972.     -- properties alone
  30973.     
  30974.     -- Adding snapshot header commands
  30975.     
  30976.     -- Snapshot header begins + Snapshot header ends +
  30977.     -- directory command + Snapshot trailer command = 3 * @addcommandcost
  30978.     select @addcommandstotal = 4
  30979.     
  30980.     -- Alternate snapshot folder = 1 * @addcommandcost
  30981.     if @alt_snapshot_folder is not null and
  30982.        @alt_snapshot_folder <> N'' and
  30983.        @snapshot_in_defaultfolder = 1
  30984.     begin
  30985.         select @addcommandstotal = @addcommandstotal + @addcommandcost
  30986.     end
  30987.  
  30988.     -- Ftp commands
  30989.     if @enabled_for_internet = 1
  30990.     begin
  30991.         -- ftp_address and ftp_port must be there +=2 * @addcommandcost
  30992.         select @addcommandstotal = @addcommandstotal + 2 * @addcommandcost
  30993.  
  30994.         -- ftp_password += 1 * @addcommandcost
  30995.         if @ftp_password is not null and
  30996.            @ftp_password <> N''
  30997.         begin
  30998.             select @addcommandstotal = @addcommandstotal + @addcommandcost
  30999.         end
  31000.         
  31001.         -- ftp_subdirectory += 1 * @addcommandcost
  31002.         if @ftp_subdirectory is not null and
  31003.            @ftp_subdirectory <> N''
  31004.         begin
  31005.             select @addcommandstotal = @addcommandstotal + 1 * @addcommandcost
  31006.         end
  31007.     end
  31008.  
  31009.     -- Compressed archive path
  31010.     if @compress_snapshot = 1
  31011.     begin
  31012.         select @addcommandstotal = @addcommandstotal + 1 * @addcommandcost
  31013.     end    
  31014.  
  31015.     -- Snapshot trailer command
  31016.     select @addcommandstotal = @addcommandstotal +  @addcommandcost
  31017.  
  31018.     -- Need to copy files?
  31019.     if @alt_snapshot_folder is not null and @alt_snapshot_folder <> N''
  31020.        and @snapshot_in_defaultfolder = 1 and @compress_snapshot = 0
  31021.     begin
  31022.         select @copysnapshot = 1
  31023.     end
  31024.  
  31025.     -- Compute per-script file post processing cost and bcp cost per 100 rows
  31026.     -- Need to delete files?
  31027.     if (@alt_snapshot_folder is null or @alt_snapshot_folder <> N''
  31028.        or @snapshot_in_defaultfolder = 0) and @compress_snapshot = 1
  31029.     begin
  31030.         select @deletefiles = 1
  31031.     end
  31032.  
  31033.     select @totalbcpcostper100 = @bcpcostper100
  31034.     -- Copy file?
  31035.     if @copysnapshot = 1
  31036.     begin
  31037.         select @scriptproccost = @scriptproccost + @copyfilecost
  31038.         select @totalbcpcostper100 = @totalbcpcostper100 + @copybcpper100
  31039.     end
  31040.  
  31041.     -- Add file to cabinet?
  31042.     if @compress_snapshot = 1
  31043.     begin
  31044.         select @scriptproccost = @scriptproccost + @addscripttocab 
  31045.         select @totalbcpcostper100 = @totalbcpcostper100 + @addbcptocabper100
  31046.     end
  31047.  
  31048.     -- Delete file?
  31049.     if @deletefiles = 1
  31050.     begin 
  31051.         select @scriptproccost = @scriptproccost + @delfilecost
  31052.         select @totalbcpcostper100 = @totalbcpcostper100 + @deletebcpper100
  31053.     end
  31054.  
  31055.     -- Pre/Post-snapshot scripts, has to be computed after the 
  31056.     -- the per-script post-processing cost is calculated 
  31057.     if @pre_snapshot_script is not null and
  31058.        @pre_snapshot_script <> N''
  31059.     begin
  31060.         -- Cost of copying the script file
  31061.         select @taskload = @copyfilecost + @scriptproccost
  31062.         insert #workload_breakdown values (N'', @zerouuid, 10, @taskload)
  31063.         -- Cost of adding the pre-snapshot command
  31064.         select @addcommandstotal = @addcommandstotal + @addcommandcost
  31065.         -- Increment scripts counter
  31066.         select @numscripts = @numscripts + 1
  31067.     end
  31068.  
  31069.     if @post_snapshot_script is not null and
  31070.        @post_snapshot_script <> N''
  31071.     begin
  31072.         -- Cost of copying the script file
  31073.         select @taskload = @copyfilecost + @scriptproccost
  31074.         insert #workload_breakdown values (N'', @zerouuid, 11, @taskload)
  31075.         -- Cost of adding the post-snapshot command
  31076.         select @addcommandstotal = @addcommandstotal + @addcommandcost
  31077.         -- Increment scripts counter
  31078.         select @numscripts = @numscripts + 1
  31079.     end
  31080.            
  31081.     -- Estimate the break down of per article tasks 
  31082.     declare hCarticles cursor local fast_forward
  31083.     for select artid, creation_script, objid, convert(int, schema_option), type, name,
  31084.                status  
  31085.           from sysmergeextendedarticlesview where pubid = @pubid 
  31086.  
  31087.     open hCarticles
  31088.    
  31089.     fetch hCarticles into @artid, @creation_script, @objid, @schema_option, @type, @name,
  31090.         @status
  31091.     while (@@fetch_status <> -1)
  31092.     begin
  31093.         if @type = 0x40 -- Schema view articles, may require index scripting
  31094.         begin
  31095.             select @taskload = 0
  31096.             -- See if a custom creation script will be used 
  31097.             if @schema_option = 0 and @creation_script is not null and
  31098.                @creation_script <> N''
  31099.             begin
  31100.                 -- Script generation
  31101.                 select @taskload = @copyfilecost + @scriptproccost
  31102.                 insert #workload_breakdown values (@name, @artid, 12, @taskload)
  31103.                 -- Cost of adding commands for the custom script
  31104.                 select @addcommandstotal = @addcommandstotal + @addcommandcost
  31105.                 -- Increment scripts counter
  31106.                 select @numscripts = @numscripts + 1
  31107.                 -- No need to worry about index script
  31108.             end
  31109.             else
  31110.             begin
  31111.                 -- Script generation 
  31112.                 select @taskload = @dmoscriptcost + @scriptproccost
  31113.                 -- Must script out schema script
  31114.                 insert #workload_breakdown values (@name, @artid, 1, @taskload)
  31115.                 -- Cost of adding the command
  31116.                 select @addcommandstotal = @addcommandstotal + @addcommandcost
  31117.                 -- Increment scripts counter
  31118.                 select @numscripts = @numscripts + 1
  31119.  
  31120.                 -- DRI script containing the view's indexes?
  31121.                 if (@schema_option & 0x50) <> 0x0
  31122.                 begin
  31123.                     -- Cost of script generation
  31124.                     select @taskload = @dmoscriptcost + @scriptproccost
  31125.                     insert #workload_breakdown values (@name, @artid, 9, @taskload)
  31126.                     -- Cost of adding command for the script
  31127.                     select @addcommandstotal = @addcommandstotal + @addcommandcost
  31128.                     -- Increment scripts counter
  31129.                     select @numscripts = @numscripts + 1
  31130.                 end
  31131.  
  31132.                 -- Trigger script?
  31133.                 if (@schema_option & 0x100) <> 0x0
  31134.                 begin
  31135.                     -- Cost of script generation
  31136.                     select @taskload = @dmoscriptcost + @scriptproccost
  31137.                     insert #workload_breakdown values (@name, @artid, 2, @taskload)
  31138.                     -- Cost of adding command for the script
  31139.                     select @addcommandstotal = @addcommandstotal + @addcommandcost
  31140.                     -- Increment scripts counter
  31141.                     select @numscripts = @numscripts + 1
  31142.                 end 
  31143.  
  31144.                 -- XProp script?
  31145.                 if (@schema_option & 0x2000) <> 0x0
  31146.                 begin
  31147.                     -- Cost of script generation 
  31148.                     select @taskload = @dmoscriptcost + @scriptproccost
  31149.                     insert #workload_breakdown values (@name, @artid, 3, @taskload)
  31150.                     -- Cost of adding command
  31151.                     select @addcommandstotal = @addcommandstotal + @addcommandcost
  31152.                     -- Increment scripts counter
  31153.                     select @numscripts = @numscripts + 1
  31154.                 end
  31155.             end        
  31156.         end
  31157.         else if @type in (0x08, 0x18, 0x20, 0x80) -- Regular schema articles 
  31158.         begin
  31159.             select @taskload = 0
  31160.             -- See if a custom creation script will be used 
  31161.             if @schema_option = 0 and @creation_script is not null and
  31162.                @creation_script <> N''
  31163.             begin
  31164.                 -- Script generation
  31165.                 select @taskload = @copyfilecost + @scriptproccost
  31166.                 insert #workload_breakdown values (@name, @artid, 12, @taskload)
  31167.                 -- Cost of adding commands for the custom script
  31168.                 select @addcommandstotal = @addcommandstotal + @addcommandcost
  31169.                 -- Increment scripts counter
  31170.                 select @numscripts = @numscripts + 1
  31171.             end
  31172.             else 
  31173.             begin
  31174.                 -- Script generation 
  31175.                 select @taskload = @dmoscriptcost + @scriptproccost
  31176.                 -- Must script out schema script
  31177.                 insert #workload_breakdown values (@name, @artid, 1, @taskload)
  31178.                 -- Cost of adding the command
  31179.                 select @addcommandstotal = @addcommandstotal + @addcommandcost
  31180.                 -- Increment scripts counter
  31181.                 select @numscripts = @numscripts + 1
  31182.  
  31183.                 -- XProp script?
  31184.                 if (@schema_option & 0x2000) <> 0x0
  31185.                 begin
  31186.                     -- Cost of script generation 
  31187.                     select @taskload = @dmoscriptcost + @scriptproccost
  31188.                     insert #workload_breakdown values (@name, @artid, 3, @taskload)
  31189.                     -- Cost of adding command
  31190.                     select @addcommandstotal = @addcommandstotal + @addcommandcost
  31191.                 -- Increment scripts counter
  31192.                 select @numscripts = @numscripts + 1
  31193.                 end
  31194.             end
  31195.         end
  31196.         else -- Merge table articles, requires bcp
  31197.         begin
  31198.            select @taskload = 0
  31199.            -- See if a custom creation script will be used 
  31200.             if @schema_option = 0 and @creation_script is not null and
  31201.                @creation_script <> N''
  31202.             begin
  31203.                 -- Script generation
  31204.                 select @taskload = @copyfilecost + @scriptproccost
  31205.                 insert #workload_breakdown values (@name, @artid, 12, @taskload)
  31206.                 -- Cost of adding commands for the custom script
  31207.                 select @addcommandstotal = @addcommandstotal + @addcommandcost
  31208.                 -- Increment scripts counter
  31209.                 select @numscripts = @numscripts + 1
  31210.                 -- No need to worry about index script
  31211.             end
  31212.             else
  31213.             begin
  31214.                 -- Script generation 
  31215.                 select @taskload = @dmoscriptcost + @scriptproccost
  31216.                 -- Must script out schema script
  31217.                 insert #workload_breakdown values (@name, @artid, 1, @taskload)
  31218.                 -- Cost of adding the command
  31219.                 select @addcommandstotal = @addcommandstotal + @addcommandcost
  31220.                 -- Increment scripts counter
  31221.                 select @numscripts = @numscripts + 1
  31222.  
  31223.                 -- Constraint script is not optional for merge table article
  31224.                 -- Cost of script generation
  31225.                 select @taskload = @dmoscriptcost + @scriptproccost
  31226.                 insert #workload_breakdown values (@name, @artid, 9, @taskload)
  31227.                 -- Cost of adding command for the script
  31228.                 select @addcommandstotal = @addcommandstotal + @addcommandcost
  31229.                 -- Increment scripts counter
  31230.                 select @numscripts = @numscripts + 1
  31231.     
  31232.                 -- Trigger script?
  31233.                 if (@schema_option & 0x100) <> 0x0
  31234.                 begin
  31235.                     -- Cost of script generation
  31236.                     select @taskload = @dmoscriptcost + @scriptproccost
  31237.                     insert #workload_breakdown values (@name, @artid, 2, @taskload)
  31238.                     -- Cost of adding command for the script
  31239.                     select @addcommandstotal = @addcommandstotal + @addcommandcost
  31240.                     -- Increment scripts counter
  31241.                     select @numscripts = @numscripts + 1
  31242.                 end 
  31243.         
  31244.                 -- XProp script?
  31245.                 if (@schema_option & 0x2000) <> 0x0
  31246.                 begin
  31247.                     -- Cost of script generation 
  31248.                     select @taskload = @dmoscriptcost + @scriptproccost
  31249.                     insert #workload_breakdown values (@name, @artid, 3, @taskload)
  31250.                     -- Cost of adding command
  31251.                     select @addcommandstotal = @addcommandstotal + @addcommandcost
  31252.                     -- Increment scripts counter
  31253.                     select @numscripts = @numscripts + 1
  31254.                 end
  31255.             end        
  31256.  
  31257.             -- Conflict script generation and setting
  31258.             -- Cost of script generation and execution 
  31259.             select @taskload = @dmoscriptcost + @scriptexeccost + @scriptproccost
  31260.             insert #workload_breakdown values (@name, @artid, 21, @taskload)
  31261.  
  31262.             -- Get fast row count from sysindexes for bcp op estimation
  31263.             select @rowcount = 
  31264.                     case when isnull(rowcnt,0) > @maxint then @maxint / 10000
  31265.                          when isnull(rowcnt,0) > @maxint / 10000 then rowcnt / 10000
  31266.                          else isnull(rowcnt,0)
  31267.                     end
  31268.               from sysindexes 
  31269.              where id = @objid and indid in (0,1)
  31270.  
  31271.             -- For unsynced articles, we need to 
  31272.             -- 1) Add rowguid column 
  31273.             -- 2) Set article procs
  31274.             -- 3) Add merge triggers
  31275.             if @status = 1
  31276.             begin
  31277.                 -- Add rowguid column - use article row count to estimate the cost
  31278.                 select @taskload = (@rowcount * @rowguidper100) / 100
  31279.                 insert #workload_breakdown values (@name, @artid, 15, @taskload) 
  31280.       
  31281.                 -- Set article procs
  31282.                 select @taskload = @setartprocs
  31283.                 insert #workload_breakdown values (@name, @artid, 16, @taskload)
  31284.  
  31285.                 -- Add merge triggers    
  31286.                 select @taskload = @addmergetriggers 
  31287.                 insert #workload_breakdown values (@name, @artid, 17, @taskload)
  31288.  
  31289.                 -- Increment the number of unsynced articles
  31290.                 select @numunsyncedarticles = @numunsyncedarticles + 1
  31291.             end
  31292.  
  31293.             -- Increment the total row count
  31294.             select @totalrowcount = @totalrowcount + @rowcount        
  31295.  
  31296.             -- BCP computation            
  31297.             -- Bcp file generation
  31298.             select @taskload = @bcpoverhead + (@rowcount * @totalbcpcostper100) / 100 
  31299.             insert #workload_breakdown values (@name, @artid, 4, @taskload)
  31300.  
  31301.             -- Increment the table articles counter
  31302.             select @numtablearticles = @numtablearticles + 1
  31303.  
  31304.         end    
  31305.  
  31306.         -- System pre-snapshot script required?
  31307.         if @type in (0x40, 0x80)
  31308.         begin
  31309.             select @needsysprescript = 1
  31310.             -- Incrememt the number of pre-script command counter
  31311.             select @numprescriptcommands = @numprescriptcommands + 1
  31312.         end
  31313.  
  31314.         -- Increment the article count
  31315.         select @numarticles = @numarticles + 1
  31316.  
  31317.         fetch hCarticles into @artid, @creation_script, @objid, @schema_option, @type, @name,
  31318.             @status
  31319.     end
  31320.         
  31321.     -- The cost of making publication views depends upon the 
  31322.     -- number of unsynced articles
  31323.     if @numunsyncedarticles <> 0
  31324.     begin
  31325.         select @taskload = @numunsyncedarticles * @pubviewperarticle 
  31326.         insert #workload_breakdown values (N'', @zerouuid, 22, @taskload) 
  31327.     end
  31328.  
  31329.     -- Make publication generation - roughly proportional to the number of table
  31330.     -- articles we have
  31331.     select @taskload = @numtablearticles * @genperarticle
  31332.     insert #workload_breakdown values (N'', @zerouuid, 20, @taskload)
  31333.  
  31334.     -- Merge system tables processing 
  31335.     -- Script files
  31336.     select @taskload = 4 * (@dmoscriptcost + @scriptproccost)
  31337.     insert #workload_breakdown values (N'', @zerouuid, 18, @taskload)
  31338.  
  31339.     -- Cost of adding the commands
  31340.     select @addcommandcost = @addcommandcost + 4
  31341.  
  31342.     -- Bcp files - Generated only when the publication is not enabled for
  31343.     -- dynamic filters
  31344.     if @dynamic_filters = 0
  31345.     begin
  31346.         if exists (select * from sysobjects where name = N'MSmerge_contents')
  31347.         begin
  31348.             select @rowcount = 
  31349.                     case when isnull(rowcnt,0) > @maxint then @maxint / 10000
  31350.                          when isnull(rowcnt,0) > @maxint / 10000 then rowcnt / 10000
  31351.                          else isnull(rowcnt,0)       
  31352.                     end
  31353.               from sysindexes 
  31354.              where id = object_id('dbo.MSmerge_contents') 
  31355.                and indid in (0,1)
  31356.             select @systablesrowcount = @systablesrowcount + @rowcount
  31357.         end
  31358.         if exists (select * from sysobjects where name = N'MSmerge_tombstones')
  31359.         begin
  31360.             select @rowcount = 
  31361.                     case when isnull(rowcnt,0) > @maxint then @maxint / 10000
  31362.                          when isnull(rowcnt,0) > @maxint / 10000 then rowcnt / 10000
  31363.                          else isnull(rowcnt,0)       
  31364.                     end
  31365.               from sysindexes 
  31366.              where id = object_id('dbo.MSmerge_tombstoness') 
  31367.                and indid in (0,1)
  31368.             select @systablesrowcount = @systablesrowcount + @rowcount
  31369.         end
  31370.         if exists (select * from sysobjects where name = N'MSmerge_genhistory')
  31371.         begin
  31372.             select @rowcount = 
  31373.                     case when isnull(rowcnt,0) > @maxint then @maxint / 10000
  31374.                          when isnull(rowcnt,0) > @maxint / 10000 then rowcnt / 10000
  31375.                          else isnull(rowcnt,0)       
  31376.                     end
  31377.               from sysindexes 
  31378.              where id = object_id('dbo.MSmerge_genhistory') 
  31379.                and indid in (0,1)
  31380.             select @systablesrowcount = @systablesrowcount + @rowcount
  31381.         end
  31382.     end
  31383.     if exists (select * from sysobjects where name = N'sysmergesubsetfilters')
  31384.     begin
  31385.         select @rowcount = count(*) from sysmergesubsetfilters
  31386.         select @systablesrowcount = @systablesrowcount + @rowcount 
  31387.     end
  31388.  
  31389.     select @taskload = (4 * @bcpoverhead) + (@systablesrowcount * @totalbcpcostper100) / 100 
  31390.     insert #workload_breakdown values (N'', @zerouuid, 19, @taskload)
  31391.     select @totalrowcount = @totalrowcount + @systablesrowcount
  31392.  
  31393.     -- System pre-snapshot script processing cost 
  31394.     if @needsysprescript = 1
  31395.     begin
  31396.         select @taskload = @syspreoverhead + 
  31397.                 (@numprescriptcommands * @syspreper2commands) / 2 +
  31398.                @scriptproccost
  31399.         insert #workload_breakdown values (N'', @zerouuid, 7, @taskload)         
  31400.         select @numscripts = @numscripts + 1
  31401.     end
  31402.  
  31403.     -- Cost of flushing folder for the scripts 
  31404.     if @compress_snapshot = 1
  31405.     begin
  31406.         select @taskload = (@numscripts * @flushper2scripts) / 2
  31407.         insert #workload_breakdown values (N'', @zerouuid, 8, @taskload) 
  31408.     end
  31409.  
  31410.     -- Cost for flushing the cabinet
  31411.     if @compress_snapshot = 1
  31412.     begin
  31413.         select @taskload = (@numscripts * @flushcabper5scripts / 5) +
  31414.                            (@totalrowcount * @flushcabper500bcprows / 500)
  31415.         insert #workload_breakdown values (N'', @zerouuid, 14, @taskload)
  31416.     end
  31417.  
  31418.     -- Add the total add commands cost
  31419.     insert #workload_breakdown values (N'', @zerouuid, 6, @addcommandstotal)
  31420.  
  31421.     -- Compute the total workload and put that in the 
  31422.     -- workload break down
  31423.     select @bigtaskload = sum(convert(bigint,taskload)) from #workload_breakdown
  31424.     select @taskload =
  31425.             case when @bigtaskload > @maxint then @maxint
  31426.             else @bigtaskload
  31427.             end
  31428.     insert #workload_breakdown values (N'', @zerouuid, 0, @taskload) 
  31429.  
  31430.     select name, taskid, taskload from #workload_breakdown order by artid, taskid asc
  31431.     drop table #workload_breakdown
  31432.     return 0
  31433.  
  31434. Failure:
  31435.     if @table_created = 1
  31436.        drop table #workload_breakdown
  31437.     return 1
  31438. end
  31439. go
  31440.  
  31441. exec dbo.sp_MS_marksystemobject sp_MSestimatemergesnapshotworkload
  31442. go            
  31443.  
  31444. grant execute on dbo.sp_MSestimatemergesnapshotworkload to public
  31445. go
  31446.  
  31447. raiserror(15339,-1,-1,'sp_MSestimatesnapshotworkload')
  31448. go
  31449. create proc sp_MSestimatesnapshotworkload (
  31450.     @publication sysname
  31451.     )
  31452. as
  31453. begin
  31454.     set nocount on
  31455.  
  31456.     declare @taskload                       int
  31457.     declare @bigtaskload                    bigint
  31458.     declare @table_created                  bit
  31459.     declare @retcode                        int
  31460.  
  31461.     -- Publication info
  31462.     declare @pubid                          int
  31463.     declare @compress_snapshot              bit
  31464.     declare @snapshot_in_defaultfolder      bit
  31465.     declare @alt_snapshot_folder            nvarchar(255)
  31466.     declare @enabled_for_internet           bit
  31467.     declare @ftp_password                   nvarchar(524) 
  31468.     declare @ftp_subdirectory               nvarchar(255)
  31469.     declare @pre_snapshot_script            nvarchar(255)
  31470.     declare @post_snapshot_script           nvarchar(255)    
  31471.  
  31472.     -- Per publication summary stats
  31473.     declare @numarticles                    int
  31474.     declare @totalrowcount                  int   
  31475.     declare @needsysprescript               bit
  31476.     declare @copysnapshot                   bit
  31477.     declare @deletefiles                    bit
  31478.     declare @scriptproccost                 int
  31479.     declare @addcommandstotal               int
  31480.     declare @numscripts                     int
  31481.     declare @totalbcpcostper100             int
  31482.     declare @numprescriptcommands           int 
  31483.  
  31484.     select @numarticles = 0
  31485.     select @totalrowcount = 0
  31486.     select @needsysprescript = 0
  31487.     select @copysnapshot = 0
  31488.     select @deletefiles = 0
  31489.     select @scriptproccost = 0
  31490.     select @deletefiles = 0
  31491.     select @addcommandstotal = 0
  31492.     select @numscripts = 0
  31493.     select @totalbcpcostper100 = 0
  31494.     select @numprescriptcommands = 0
  31495.  
  31496.     -- Per article variables
  31497.     declare @artid                          int
  31498.     declare @schema_option                  int
  31499.     declare @creation_script                nvarchar(255)
  31500.     declare @type                           tinyint
  31501.     declare @objid                          int
  31502.     declare @rowcount                       int
  31503.     declare @name                           sysname
  31504.     declare @pre_creation_command           int
  31505.  
  31506.     select @table_created = 0
  31507.  
  31508.     -- Security check
  31509.     select @retcode = 0
  31510.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  31511.     IF @@ERROR <> 0 or @retcode <> 0
  31512.         return (1)
  31513.  
  31514.     select @pubid = null
  31515.     select @compress_snapshot = 0
  31516.     select @snapshot_in_defaultfolder = 0
  31517.     select @alt_snapshot_folder = null
  31518.     select @enabled_for_internet = 0
  31519.     select @ftp_password = null
  31520.     select @ftp_subdirectory = null
  31521.     select @pre_snapshot_script = null
  31522.     select @post_snapshot_script = null
  31523.     -- Validate publication and retrieve publication information 
  31524.     select @pubid = pubid, 
  31525.            @compress_snapshot = compress_snapshot,
  31526.            @snapshot_in_defaultfolder = snapshot_in_defaultfolder,
  31527.            @alt_snapshot_folder = alt_snapshot_folder,
  31528.            @enabled_for_internet = enabled_for_internet,
  31529.            @ftp_password = ftp_password,
  31530.            @ftp_subdirectory = ftp_subdirectory,
  31531.            @pre_snapshot_script = pre_snapshot_script,
  31532.            @post_snapshot_script = post_snapshot_script
  31533.            from syspublications
  31534.      where name = @publication
  31535.     if @pubid = null
  31536.     begin   
  31537.         raiserror(20026, 11, -1, @publication)
  31538.         return (1)
  31539.     end
  31540.  
  31541.     -- An artid of -1 means the task is a per publication
  31542.     -- task
  31543.  
  31544.     -- Task id mapping - This is the list of task whose completion can be 
  31545.     -- reported by the snapshot agent
  31546.     -- 0 - Total workload (not really a task)
  31547.     -- 1 - Schema script generation
  31548.     -- 2 - Trigger script generation 
  31549.     -- 3 - XProp script generation
  31550.     -- 4 - Bcp file generation
  31551.     -- 5 - Activating subscription (estimate number of subscriptions?)
  31552.     -- 6 - Adding snapshot commands
  31553.     -- 7 - System pre-script generation
  31554.     -- 8 - Flushing folder for scripts
  31555.     -- 9 - Constraint script generation
  31556.     -- 10 - Copying pre-script
  31557.     -- 11 - Copying post-script
  31558.     -- 12 - Copying custom schema creation script
  31559.     -- 13 - Index script generation
  31560.     -- 14 - Flushing the cabinet
  31561.     -- 15 - Adding rowguid column
  31562.     -- 16 - Setting article procs
  31563.     -- 17 - Adding merge triggers
  31564.     -- 18 - Generating system table scripts
  31565.     -- 19 - Generating system table bcp files
  31566.     -- 20 - Making publication generation
  31567.     -- 21 - Generating and setting conflict script
  31568.     -- 22 - Generating publication views
  31569.  
  31570.     -- Weights and overheads
  31571.     -- DMO Script generation - 7/script
  31572.     -- BCP 5 overhead + 5/100 rows
  31573.     -- Flush folder for bcp 2/100 rows
  31574.     -- Delete file 2
  31575.     -- System pre-snapshot script 1 overhead + 0.5/pre-creation command
  31576.     -- Copying user file 2
  31577.     -- Adding file to cabinet 1 for scripts and 1/100 rows in bcp file
  31578.     -- Loading article info 3
  31579.     -- Delete bcp file 2/100rows 
  31580.     -- Copy bcp file  2/100rows  
  31581.     -- Flush scripts folder 1/2 scripts
  31582.     -- Flushing cabinet per 5 scripts 1
  31583.     -- Flushing cabinet per 500 rows 1
  31584.  
  31585.     -- Here is the list of cost factors 
  31586.     declare @addcommandcost     int
  31587.     declare @dmoscriptcost      int
  31588.     declare @bcpoverhead        int
  31589.     declare @bcpcostper100      int
  31590.     declare @flushper100        int
  31591.     declare @flushperscript     int
  31592.     declare @delfilecost        int
  31593.     declare @syspreoverhead     int
  31594.     declare @syspreper2commands int
  31595.     declare @addbcptocabper100  int
  31596.     declare @addscripttocab     int
  31597.     declare @copyfilecost       int
  31598.     declare @loadartinfo        int    
  31599.     declare @deletebcpper100    int
  31600.     declare @copybcpper100      int
  31601.     declare @flushper2scripts   int
  31602.     declare @flushcabper5scripts int
  31603.     declare @flushcabper500bcprows int
  31604.     declare @maxint             int
  31605.  
  31606.     select @addcommandcost = 2
  31607.     select @dmoscriptcost = 7
  31608.     select @bcpcostper100 = 20
  31609.     select @bcpoverhead = 2
  31610.     select @flushper100 = 2
  31611.     select @flushperscript = 3
  31612.     select @delfilecost = 2
  31613.     select @syspreoverhead = 1
  31614.     select @syspreper2commands = 1
  31615.     select @addbcptocabper100 = 1
  31616.     select @addscripttocab = 1
  31617.     select @copyfilecost = 2
  31618.     select @loadartinfo = 3    
  31619.     select @deletebcpper100 = 1
  31620.     select @copybcpper100 = 2
  31621.     select @flushper2scripts = 1
  31622.     select @flushcabper5scripts = 1
  31623.     select @flushcabper500bcprows = 1
  31624.     select @maxint = 2147483647
  31625.  
  31626.     create table #workload_breakdown
  31627.     (
  31628.         name        sysname collate database_default,
  31629.         artid       int,
  31630.         taskid      int,
  31631.         taskload    int
  31632.     )
  31633.     if @@error <> 0
  31634.         goto Failure
  31635.  
  31636.     select @table_created = 1
  31637.  
  31638.     -- Per publication work load estimate that can be done using publication
  31639.     -- properties alone
  31640.     
  31641.     -- Adding snapshot header commands
  31642.     
  31643.     -- Snapshot header begins + Snapshot header ends +
  31644.     -- directory command + Snapshot trailer command = 3 * @addcommandcost
  31645.     select @addcommandstotal = 4
  31646.     
  31647.     -- Alternate snapshot folder = 1 * @addcommandcost
  31648.     if @alt_snapshot_folder is not null and
  31649.        @alt_snapshot_folder <> N'' and
  31650.        @snapshot_in_defaultfolder = 1
  31651.     begin
  31652.         select @addcommandstotal = @addcommandstotal + @addcommandcost
  31653.     end
  31654.  
  31655.     -- Ftp commands
  31656.     if @enabled_for_internet = 1
  31657.     begin
  31658.         -- ftp_address and ftp_port must be there +=2 * @addcommandcost
  31659.         select @addcommandstotal = @addcommandstotal + 2 * @addcommandcost
  31660.  
  31661.         -- ftp_password += 1 * @addcommandcost
  31662.         if @ftp_password is not null and
  31663.            @ftp_password <> N''
  31664.         begin
  31665.             select @addcommandstotal = @addcommandstotal + @addcommandcost
  31666.         end
  31667.         
  31668.         -- ftp_subdirectory += 1 * @addcommandcost
  31669.         if @ftp_subdirectory is not null and
  31670.            @ftp_subdirectory <> N''
  31671.         begin
  31672.             select @addcommandstotal = @addcommandstotal + 1 * @addcommandcost
  31673.         end
  31674.     end
  31675.  
  31676.     -- Compressed archive path
  31677.     if @compress_snapshot = 1
  31678.     begin
  31679.         select @addcommandstotal = @addcommandstotal + 1 * @addcommandcost
  31680.     end    
  31681.  
  31682.     -- Snapshot trailer command
  31683.     select @addcommandstotal = @addcommandstotal +  @addcommandcost
  31684.  
  31685.     -- Need to copy files?
  31686.     if @alt_snapshot_folder is not null and @alt_snapshot_folder <> N''
  31687.        and @snapshot_in_defaultfolder = 1 and @compress_snapshot = 0
  31688.     begin
  31689.         select @copysnapshot = 1
  31690.     end
  31691.  
  31692.     -- Compute per-script file post processing cost and bcp cost per 100 rows
  31693.     -- Need to delete files?
  31694.     if (@alt_snapshot_folder is null or @alt_snapshot_folder <> N''
  31695.        or @snapshot_in_defaultfolder = 0) and @compress_snapshot = 1
  31696.     begin
  31697.         select @deletefiles = 1
  31698.     end
  31699.  
  31700.     select @totalbcpcostper100 = @bcpcostper100
  31701.     -- Copy file?
  31702.     if @copysnapshot = 1
  31703.     begin
  31704.         select @scriptproccost = @scriptproccost + @copyfilecost
  31705.         select @to